<?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[Andrew Jaffee - AppCoda]]></title><description><![CDATA[AppCoda is one of the leading iOS programming communities. Our goal is to empower everyone to create apps through easy-to-understand tutorials. Learn by doing is the heart of our learning materials. ]]></description><link>https://www.appcoda.com/</link><image><url>https://www.appcoda.com/favicon.png</url><title>Andrew Jaffee - AppCoda</title><link>https://www.appcoda.com/</link></image><generator>Ghost 5.83</generator><lastBuildDate>Thu, 09 Apr 2026 12:36:47 GMT</lastBuildDate><atom:link href="https://www.appcoda.com/author/andrewjaffee/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Using SwiftUI and WidgetKit to Make Your App Content Indispensable]]></title><description><![CDATA[<!--kg-card-begin: html-->

<p>By using a combination of <a href="https://developer.apple.com/documentation/swiftui/?ref=appcoda.com">SwiftUI</a> and <a href="https://developer.apple.com/documentation/widgetkit?ref=appcoda.com">WidgetKit</a>, you can increase the visibility of your app&#x2019;s content and enhance the user experience by placing one or more &#x201C;widgets&#x201D; on the user&#x2019;s iOS Home screen, macOS Notification Center, and/or iOS Today View. </p>



<p>Widgets should</p>]]></description><link>https://www.appcoda.com/swiftui-widgetkit/</link><guid isPermaLink="false">66612a0f166d3c03cf0114fc</guid><category><![CDATA[SwiftUI]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Mon, 22 Nov 2021 01:19:55 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2021/11/fsujojqv_yg.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->

<img src="https://www.appcoda.com/content/images/wordpress/2021/11/fsujojqv_yg.jpg" alt="Using SwiftUI and WidgetKit to Make Your App Content Indispensable"><p>By using a combination of <a href="https://developer.apple.com/documentation/swiftui/?ref=appcoda.com">SwiftUI</a> and <a href="https://developer.apple.com/documentation/widgetkit?ref=appcoda.com">WidgetKit</a>, you can increase the visibility of your app&#x2019;s content and enhance the user experience by placing one or more &#x201C;widgets&#x201D; on the user&#x2019;s iOS Home screen, macOS Notification Center, and/or iOS Today View. </p>



<p>Widgets should display your app&#x2019;s most relevant content, allowing users to get important information with a glance. When a user taps/clicks a widget, they go straight to your app and should land on a page that gives them more details about what they just glanced at. Take a look at your iPhone&#x2019;s Today View right now. There are widgets for weather, battery power, maps, stock exchanges &#x2014; with many more available. For example, you can get an almost-instant read on the current atmospheric conditions by glancing at one of several available weather widgets. This time of year, before I leave the house, I glance at the weather widget to determine if I need a coat and hat before going outside. If I want to get the forecast for later in the day, I just tap on that weather widget to open the respective weather app.</p>



<p>Since widgets display content with SwiftUI views, they are generally easy to create and portable across Apple&#x2019;s devices, like iPhones and Macs. Each of your apps can provide multiple widgets, multiple instances of the same or different widgets, and three different sizes of the same widgets.</p>



<p>Let&#x2019;s talk about at an example of design considerations for building a widget, from my <a href="https://github.com/appcoda/SwiftUI-Widget-Demo?ref=appcoda.com" class="rank-math-link">sample project</a>. You should click that link and download my project to follow along with this article. I used Xcode 13.1 to write this sample app and iOS 15.0 on the Simulator and on an iPhone 12 to test.</p>



<p>My &#x201C;Events&#x201D; app has a widget that shows the important events that occur during a workday along with the times at which they occur. Look at the following two images. The first highlights my widget showing the events of the day in fast motion, because we wouldn&#x2019;t want to wait to watch the widget over a 15-hour period. The widget simply shows the nearest-occurring event and its time; information that can be seen at a glance. The second image shows what happens when you tap on the widget: the app opens showing all the events of the day including the one that was being shown in the widget at the time of the tap. Remember that this app is a proof of concept highlighting WidgetKit and SwiftUI, and is not fully-functional.</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="294" height="574" src="https://www.appcoda.com/content/images/wordpress/2021/11/ClickOnWidget.gif" alt="Using SwiftUI and WidgetKit to Make Your App Content Indispensable" class="wp-image-19702"></figure></div>



<p>It should be apparent to you by now that, because of a widget&#x2019;s limited amount of space, it should only display information that users see as most valuable in your app. Don&#x2019;t clutter things up. Design for simplicity, ease of use, and elegance.</p>



<p>Because widgets are portable between iOS and macOS, are pretty small, and should convey concise, glanceable information, SwiftUI is the perfect tool to use for building their user interfaces. Indeed, WidgetKit requires that you use SwiftUI views to design and render widgets&#x2019; content.</p>



<h2 class="wp-block-heading">A word about my sample app</h2>



<p>The sample app that we&#x2019;ll walk through in this article is very simple and not fully functional on purpose. I want you to get a basic understanding of SwiftUI and WidgetKit without getting bogged down in a bunch of implementation details about how a daily to-do list app would be written. My app implements just enough of a to-do list to introduce you to SwiftUI and WidgetKit; the rest is a facade.</p>



<p>So, if fully functional, my app would allow a user to define 5 to 6 essential life events in a day, assign times to those events, and, at any time, glance at the widget to see the nearest approaching event, based on some type of timing algorithm. If the app was completed, tapping on the widget would take a user to a detail screen for the nearest event where one could, say, make some notes, set a reminder or alarm, add contacts, add directions, then go back to the main summary screen showing a list of all the day&#x2019;s events and times, and edit another event. Since my app is still a prototype, when the user taps on the widget (or opens the app itself), he or she is sent directly to a screen to see a read-only list of events and times.</p>



<h2 class="wp-block-heading">Creating the base app</h2>



<p>Let&#x2019;s walk through the steps I went through to develop my sample &#x201C;Events&#x201D; app. I made it a SwiftUI-based app. Open Xcode 13.x and go to:</p>



<ul><li><em>New</em> &gt; <em>Project&#x2026;</em></li><li>On the <em>Choose a template for your new project:</em> screen, select <em>iOS</em> and <em>App</em>, then click <em>Next</em>.</li><li>On the <em>Choose options for your new project:</em> screen, fill in <em>Product Name:</em> with &#x201C;Events,&#x201D; select your own <em>Team:</em>, set your own <em>Organization Identifier:</em>, set the <em>Interface:</em> to &#x201C;SwiftUI,&#x201D; set the &#x201C;Language:&#x201D; to &#x201C;Swift,&#x201D; then click <em>Next</em>.</li><li>Select the new project location and click <em>Create</em>.</li></ul>



<p>The new app will have two code files, &#x201C;EventsApp.swift&#x201D; and &#x201C;ContentView.swift.&#x201D; We&#x2019;ll leave &#x201C;EventsApp.swift&#x201D; alone. It&#x2019;s custom <code>App</code> protocol conformer, <code>EventsApp</code>, provides the entry point into the app and will render the simple user interface defined in &#x201C;ContentView.swift.&#x201D;</p>



<p>Take a look at &#x201C;ContentView.swift.&#x201D; I wrote a simple declarative SwiftUI user interface (UI) using the <code>struct</code> named <code>ContentView</code>. The app&#x2019;s entire UI is in the <code>body</code> member of the <code>ContentView</code>:</p>



<pre class="wp-block-code"><code>import SwiftUI

let events = [&quot;Wake up&quot;, &quot;Breakfast&quot;, &quot;Go to work&quot;, &quot;Lunch&quot;, &quot;Come home&quot;, &quot;Go to sleep&quot;]
let eventTimes = [&quot;7:00 AM&quot;, &quot;8:00 AM&quot;, &quot;8:30 AM&quot;, &quot;12:00 PM&quot;, &quot;5:00 PM&quot;, &quot;11:00 PM&quot;]

struct ContentView: View {

    var body: some View {
    
        // Screen title
        Text(&quot;Daily Events&quot;).bold().italic().padding()
    
        // List of daily events with times
        Form {
            ForEach(0..&lt;events.count) { event in
                Text(&quot;- \(events[event]) [ \(eventTimes[event]) ]&quot;)
            }
        }.padding().border(Color.blue)
    
    } // end body

} // end ContentView</code></pre>



<p>First, I used a <code>Text</code> view to give my list of events a title, using some view modifiers to highlight that title (<code>.bold().italic().padding()</code>). Then I used a <code>Form</code> view as the main container for the app&#x2019;s list of events because, in real life, I&#x2019;d allow editing of my events here. Right now, the app only displays the events and their times read-only, but always think ahead. The <code>ForEach</code> writes out the events and their respective times as <code>Text</code> views, one per line, for all to-do list items that I&#x2019;ve stored in arrays. The <code>Form</code> has a colored border and some padding around it. There&#x2019;s a reason I used 2 arrays and it has to do with widgets auto-updating, but that&#x2019;s beyond the scope of this article.</p>



<p>Running the &#x201C;Events&#x201D; app now shows this screen:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2021/11/EventsMainScreen-517x1024.png" alt="Using SwiftUI and WidgetKit to Make Your App Content Indispensable" class="wp-image-19703" width="259" height="512" srcset="https://www.appcoda.com/content/images/wordpress/2021/11/EventsMainScreen-517x1024.png 517w, https://www.appcoda.com/content/images/wordpress/2021/11/EventsMainScreen-152x300.png 152w, https://www.appcoda.com/content/images/wordpress/2021/11/EventsMainScreen-200x396.png 200w, https://www.appcoda.com/content/images/wordpress/2021/11/EventsMainScreen-400x792.png 400w, https://www.appcoda.com/content/images/wordpress/2021/11/EventsMainScreen-50x99.png 50w, https://www.appcoda.com/content/images/wordpress/2021/11/EventsMainScreen.png 584w" sizes="(max-width: 259px) 100vw, 259px"></figure></div>



<p>For those of you following along, test your &#x201C;Events&#x201D; app and make sure it looks like the previous picture.</p>



<h2 class="wp-block-heading">Adding the WidgetKit extension</h2>



<p>Widget functionality can be added to the SwiftUI &#x201C;Events&#x201D; app I started up above. All&#x2019;s I have to do is to add a new target &#x2014; a WidgetKit extension &#x2014; to my existing app. Head back to Xcode 13 and go to:</p>



<ul><li><em>File</em> &gt; <em>New</em> &gt; <em>Target&#x2026;</em></li><li>On the <em>Choose a template for your new target:</em> screen, select <em>iOS</em> and <em>Widget Extension</em>, then click <em>Next</em>.</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="732" src="https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-1024x732.png" alt="Using SwiftUI and WidgetKit to Make Your App Content Indispensable" class="wp-image-19706" srcset="https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-1024x732.png 1024w, https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-420x300.png 420w, https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-200x143.png 200w, https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-768x549.png 768w, https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-1240x886.png 1240w, https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-860x615.png 860w, https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-680x486.png 680w, https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-400x286.png 400w, https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension-50x36.png 50w, https://www.appcoda.com/content/images/wordpress/2021/11/AddWidgetExtension.png 1458w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<ul><li>On the <em>Choose options for your new target:</em> screen, fill in <em>Product Name:</em> with &#x201C;EventTimes,&#x201D; select your own <em>Team:</em>, set your own <em>Organization Identifier:</em> (same as &#x201C;Events&#x201D; app), <strong>do not</strong> set the <em>Include Configuration Intent</em>, make sure that &#x201C;Project:&#x201D; and &#x201C;Embed in Application:&#x201D; are both set to &#x201C;Events,&#x201D; and then click <em>Finish</em>.</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="726" src="https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-1024x726.png" alt="Using SwiftUI and WidgetKit to Make Your App Content Indispensable" class="wp-image-19708" srcset="https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-1024x726.png 1024w, https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-423x300.png 423w, https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-200x142.png 200w, https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-768x545.png 768w, https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-1240x879.png 1240w, https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-860x610.png 860w, https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-680x482.png 680w, https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-400x284.png 400w, https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions-50x35.png 50w, https://www.appcoda.com/content/images/wordpress/2021/11/ConfigExtensionTargetOptions.png 1464w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<ul><li>You&#x2019;ll be prompted to activate your new &#x201C;EventTimesExtension&#x201D; scheme; make sure you press the &#x201C;Activate&#x201D; button now.</li></ul>



<p>A few items have been added to your &#x201C;Events&#x201D; app project, most notably, the &#x201C;EventTimes.swift&#x201D; WidgetKit code and the <code>WidgetKit.framework</code>. We&#x2019;ll spend most of the rest of the article discussing &#x201C;EventTimes.swift.&#x201D;</p>



<h2 class="wp-block-heading">Data sharing between the app and widget?</h2>



<p>Notice that I&#x2019;ve defined the same data model (2 arrays) at the top of the extension&#x2019;s &#x201C;EventTimes.swift&#x201D; that I already defined in the containing app&#x2019;s &#x201C;ContentView.swift&#x201D;:</p>



<pre class="wp-block-code"><code>let events = [&quot;Wake up&quot;, &quot;Breakfast&quot;, &quot;Go to work&quot;, &quot;Lunch&quot;, &quot;Come home&quot;, &quot;Go to sleep&quot;]
let eventTimes = [&quot;7:00 AM&quot;, &quot;8:00 AM&quot;, &quot;8:30 AM&quot;, &quot;12:00 PM&quot;, &quot;5:00 PM&quot;, &quot;11:00 PM&quot;]</code></pre>



<p>Remember that <a class="rank-math-link" href="https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html?ref=appcoda.com">&#x201C;Even though an app extension bundle is nested within its containing app&#x2019;s bundle, the running app extension and containing app have no direct access to each other&#x2019;s containers.&#x201D;</a> In other words, the 2 arrays defined in just the containing app are not accessible to the extension and vice versa. One solution would be to define an app group to which both the &#x201C;Events&#x201D; app and &#x201C;EventTimesExtension&#x201D; extension belong. They could then share the same data model. But that is way beyond the scope of this article &#x2014; and I already wrote a tutorial on app groups for AppCoda which I urge you to read: <a href="https://www.appcoda.com/app-group-macos-ios-communication/">&#x201C;Using App Groups for communication between macOS/iOS apps from the Same Vendor&#x201D;</a>.</p>



<h2 class="wp-block-heading">How WidgetKit works</h2>



<p>Widgets are driven by, like many other aspects of our reality, <strong>time</strong>. With my &#x201C;Events&#x201D; app and widget, we have a relatively fixed list of events that occur throughout the day. What drives the updating of the widget to show the next nearest coming-up event is that event&#x2019;s time. Think of the iPhone weather widget. It also is driven by time, probably polling a server every 30 seconds so it can update the current conditions, the current temperature, and the day&#x2019;s current high and low.</p>



<p>Let&#x2019;s go through the code in the WidgetKit extension&#x2019;s &#x201C;EventTimes.swift&#x201D; file from top to bottom, even though that might not may be the most logical order. But if I jump around, you&#x2019;re likely to get confused &#x2014; plus I urge you to compare my version of the file to the template version as first generated when you created the WidgetKit extension.</p>



<p>Let&#x2019;s start at the top of the file:</p>



<pre class="wp-block-code"><code>import WidgetKit
import SwiftUI

let events = [&quot;Wake up&quot;, &quot;Breakfast&quot;, &quot;Go to work&quot;, &quot;Lunch&quot;, &quot;Come home&quot;, &quot;Go to sleep&quot;]
let eventTimes = [&quot;7:00 AM&quot;, &quot;8:00 AM&quot;, &quot;8:30 AM&quot;, &quot;12:00 PM&quot;, &quot;5:00 PM&quot;, &quot;11:00 PM&quot;]
var currentEvent = 0

struct Provider: TimelineProvider {
    func placeholder(in context: Context) -&gt; SimpleEntry {
        SimpleEntry(date: Date(), eventName: &quot;Daily event&quot;, eventTime: &quot;N/A&quot;)
    }

.
.
.</code></pre>



<p>From the first <code>struct</code> we encounter, of type <code>TimelineProvider</code>, you can see why I said that widgets are driven by time. The <code>placeholder</code> function <a href="https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension?ref=appcoda.com">&#x201C;displays a generic representation of your widget, giving the user a general idea of what the widget shows&#x201D;</a>. It is called if your widget is displayed but no real data is ready to be displayed, perhaps because the containing app hasn&#x2019;t been configured or established network connections yet. <code>SimpleEntry</code> is the <code>struct</code> that holds instances of data that are shown one at a time in your widget. To be specific, this <code>SimpleEntry</code> reference is the <code>struct</code> constructor that returns an instance.</p>



<pre class="wp-block-code"><code>.
.
.

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -&gt; ()) {
        let entry = SimpleEntry(date: Date(), eventName: events[currentEvent], eventTime: eventTimes[currentEvent])
        completion(entry)
    }

.
.
.</code></pre>



<p>The <code>getSnapshot</code> function provides an app timeline entry for the current time (and perhaps state) of the widget. For my &#x201C;Events&#x201D; app, this would be the nearest event in time in your daily schedule about to occur.</p>



<pre class="wp-block-code"><code>.
.
.

    func getTimeline(in context: Context, completion: @escaping (Timeline&lt;Entry&gt;) -&gt; ()) {
        var entries: [SimpleEntry] = []

        // Generate a timeline consisting of six entries an second apart, starting from the current time.
        let currentDate = Date()
    
        for timeOffset in 0 ..&lt; events.count {
            let entryDate = Calendar.current.date(byAdding: .second, value: timeOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate, eventName: events[timeOffset], eventTime: eventTimes[timeOffset])
            entries.append(entry)
        }
        currentEvent = 0
    
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    } // end getTimeline

.
.
.</code></pre>



<p>For a static prototype like my sample &#x201C;Events&#x201D; app, the <code>getTimeline</code> function can build the entire timeline to be displayed in my widget. Because of the <code>policy: .atEnd</code>, the timeline is created over and over. I already explained why a <strong>real</strong> version of my &#x201C;Events&#x201D; app would need a more sophisticated algorithm to calculate a timeline of the &#x201C;next, nearest&#x201D; event relative to the current point in time. For a weather app, some type of polling algorithm could be used to make network requests to get the current conditions for the current times throughout the day.</p>



<pre class="wp-block-code"><code>struct SimpleEntry: TimelineEntry {
    let date: Date
    let eventName: String
    let eventTime: String
}</code></pre>



<p>As I mentioned above, the <code>SimpleEntry</code> is the <code>struct</code> that holds instances of data that are shown one at a time in your widget. Note that the <code>date</code> is essential to a timeline.</p>



<pre class="wp-block-code"><code>struct EventTimesEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        VStack {
            Text(entry.eventTime)
            Text(entry.eventName)
        }
    }
} // end EventTimesEntryView</code></pre>



<p>This is the SwiftUI I used to display the widget. Do I even need to explain what I&#x2019;m drawing here? Just look at my widget. It just amazes me how I can write such short, simple, and elegant code to get a UI. The declarative UI is here!</p>



<pre class="wp-block-code"><code>@main
struct EventTimes: Widget {
    let kind: String = &quot;EventTimes&quot;

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            EventTimesEntryView(entry: entry)
        }
        .configurationDisplayName(&quot;My Daily Events&quot;)
        .description(&quot;Shows my typical workday schedule.&quot;)
    }
} // end EventTimes</code></pre>



<p>The <code>@main</code> attribute specifies the single entry point to my <code>Widget</code> extension. My widget is given a string tag for system identification purposes. I&#x2019;m specifying the SwiftUI that my widget uses and I provide template text that people will see when they look up my widget so they can add it to my iPhone Home or Today View screens, as described in the next section.</p>



<h2 class="wp-block-heading">Adding widgets after the app is installed</h2>



<p>Once you install my sample app on an iPhone, you want to install one or more instances of its widget in one or more of the three available sizes. This ani-GIF shows you how to install a widget on the Home screen:</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="294" height="574" src="https://www.appcoda.com/content/images/wordpress/2021/11/AddNewWidget.gif" alt="Using SwiftUI and WidgetKit to Make Your App Content Indispensable" class="wp-image-19709"></figure></div>



<p>Note that I started the process by long-pressing on empty Home screen space. You can follow the same process on the Today View or, instead of starting by long-pressing, you can scroll down to the bottom of the page and tap the &#x201C;Edit&#x201D; button.</p>



<h2 class="wp-block-heading">Static versus user-configurable widgets</h2>



<p>Mainly because my &#x201C;Events&#x201D; app and widget are proofs of concept, they are static. While I&#x2019;ve mentioned possibilities for editing the events and times, those values are currently fixed. But you can make your widget user-configurable. When the good folks who were writing the iPhone weather app added their widget extension, they ticked the <code>Include Configuration Intent</code> checkbox &#x2014; that&#x2019;s the checkbox we <strong>didn&#x2019;t</strong> tick.</p>



<p>To make a long story short, you can configure the weather widget by long-tapping it until the context menu appears and selecting the &#x201C;Edit Widget&#x201D; item. The widget &#x201C;flips over&#x201D; to present an interface that allows you select from a list of nationwide locations that the widget will then show weather snapshots for.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Adding a widget to your app can add a whole lot of value to your app. You can make it so much more useful by allowing one glance to give users the gist of the main purpose of your app. Think of ways to make your apps <strong>indispensable</strong> to users &#x2014; an essential part of their lives. Widgets are one of the best ways I&#x2019;ve seen in recent years to accomplish this lofty goal.</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Deep Dive into Swift 5.5's Async/await Concurrency Model]]></title><description><![CDATA[<!--kg-card-begin: html-->

<p>In designing the <code>async</code>/<code>await</code> construct, Apple is hoping to increase the readability, and thus maintainability, of implementing <a href="http://iosbrain.com/blog/2017/02/06/concurrency-in-ios-queues-and-other-definitions-in-grand-central-dispatch-gcd-with-swift-3/?ref=appcoda.com#concurrency">concurrency/parallelism</a> in Swift. What I see in it are attempts:</p>



<ul><li>to make asynchronous/parallel code <em>almost</em> look like synchronous/sequential code; and,</li><li>to make asynchronous/parallel code much more semantically clear</li></ul>]]></description><link>https://www.appcoda.com/async-await-concurrency/</link><guid isPermaLink="false">66612a0f166d3c03cf0114f5</guid><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Mon, 05 Jul 2021 16:20:00 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2021/07/muohbrfgeqy.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->

<img src="https://www.appcoda.com/content/images/wordpress/2021/07/muohbrfgeqy.jpg" alt="Deep Dive into Swift 5.5&apos;s Async/await Concurrency Model"><p>In designing the <code>async</code>/<code>await</code> construct, Apple is hoping to increase the readability, and thus maintainability, of implementing <a href="http://iosbrain.com/blog/2017/02/06/concurrency-in-ios-queues-and-other-definitions-in-grand-central-dispatch-gcd-with-swift-3/?ref=appcoda.com#concurrency">concurrency/parallelism</a> in Swift. What I see in it are attempts:</p>



<ul><li>to make asynchronous/parallel code <em>almost</em> look like synchronous/sequential code; and,</li><li>to make asynchronous/parallel code much more semantically clear (more readable, less verbose, compact, doing what it says).</li></ul>



<p>These are laudable and ambitious goals, but I&#x2019;d say Apple&#x2019;s heading in the right direction. I&#x2019;m glad because I write a lot a asynchronous code to keep my apps responsive &#x2014; to create the best possible user experience for my customers. I have a feeling that most of you write a lot of concurrent code, too.</p>



<p>We&#x2019;ll walk through how to use <code>async</code>/<code>await</code> in detail, but I will limit my discussion to it. You need to understand <code>async</code>/<code>await</code> before trying to use Swift&#x2019;s other new concurrency features, like actors, continuations, the <code>AsyncSequence</code> protocol, the <code>TaskGroup</code> generic structure, task cancellation, and a few other concepts.</p>



<p>The Swift team has added hundreds of <code>async</code> (or &#x201C;awaitable&#x201D;) methods to the language, but I&#x2019;d like you to focus on the <em>pattern</em> I use to implement most any call involving <code>async</code>/<code>await</code>, not on specific functions. To take an even broader view, I&#x2019;ll compare using Swift&#x2019;s <code>async</code>/<code>await</code> to using Swift&#x2019;s <a href="https://www.appcoda.com/grand-central-dispatch/" class="rank-math-link">Grand Central Dispatch (GCD)</a> implementation. Both technologies offer &#x201C;generic&#x201D; support for parallelism. In other words, they both can support asynchronous/parallel code in a wide variety of applications, from long-running multi-step mathematical computations to large file downloads that all need to be run in the background. We&#x2019;ll go over a common <code>async</code>/<code>await</code> beginner&#x2019;s pitfall and finally end with some advice about where to go next with Swift concurrency.</p>



<p>Please note that <code>async</code>/<code>await</code> is <strong>not unique to Swift</strong>. Javascript, C++, Python, and C# are some examples of languages which support this construct. Also note that while <code>async</code>/<code>await</code> is nice to have, I wouldn&#x2019;t want to give up access to GCD. It&#x2019;s too powerful, despite its use of closures.</p>



<p>Please download <a href="https://github.com/appcoda/Async-Await-Swift-Demo?ref=appcoda.com" class="rank-math-link">my sample Xcode 13 beta project</a>, written in Swift 5.5, essential for getting the most out of this tutorial. The Base SDK is iOS 15 beta and I used an iPhone 12 Pro Max for the base UI layout in my storyboard.</p>



<h2 class="wp-block-heading">The heart of the problem</h2>



<p>When faced with writing concurrent/asynchronous code, Swift developers are used to submitting a specific task, like downloading a big file, and then waiting for the download to finish in a completion handler or delegate callback. If you review an example of using Apple&#x2019;s <a href="https://developer.apple.com/documentation/foundation/urlsession/1411511-downloadtask?ref=appcoda.com"><code>downloadTask(with:completionHandler:)</code></a> SDK call that <a href="https://www.appcoda.com/mvvm-vs-mvc/">I used in another article right here on AppCoda</a>, you&#x2019;ll see that the code is a bit awkward, verbose, complex, hard to read, and spread out. Look at where I have to call <code>task.resume()</code> to start the download. Note that I defined the <code>ImageDownloadCompletionClosure</code> elsewhere in the code. It&#x2019;s not super intuitive.</p>



<pre class="wp-block-code"><code>...
func download(completionHanlder: @escaping ImageDownloadCompletionClosure)
{

    let sessionConfig = URLSessionConfiguration.default
    let session = URLSession(configuration: sessionConfig)
    let request = URLRequest(url:imageURL)

    let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in

        if let tempLocalUrl = tempLocalUrl, error == nil {
            if let statusCode = (response as? HTTPURLResponse)?.statusCode {
                let rawImageData = NSData(contentsOf: tempLocalUrl)
                completionHanlder(rawImageData!)
                print(&quot;Successfully downloaded. Status code: \(statusCode)&quot;)
            }
        } else {
            print(&quot;Error took place while downloading a file. Error description: \(String(describing: error?.localizedDescription))&quot;)
        }
    } // end let task

    task.resume()

} // end func download
...</code></pre>



<p>Apple, language architects, and many developers feel that the <code>block</code>&#x2013;<code>completion handler</code> model is hard to read, especially when you&#x2019;re nesting calls of this type. As <a class="rank-math-link" href="https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html?ref=appcoda.com">Apple puts it</a>:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>&#x2026;Even in [the] simple[st] case, because the code has to be written as a series of completion handlers, you end up writing nested closures. In this style, more complex code with deep nesting can quickly become unwieldy.</p></blockquote>



<p>So, to nested completion handlers, add error checking, like <a href="http://iosbrain.com/blog/2018/08/04/controlling-chaos-error-checking-in-swift-4-with-if-let-guard-and-failable-initializers/?ref=appcoda.com"><code>guard</code>, <code>if let</code></a>, <a class="rank-math-link" href="http://iosbrain.com/blog/2018/05/01/controlling-chaos-error-handling-in-swift-4-with-do-try-catch-defer-throw-throws-error-and-nserror/?ref=appcoda.com"><code>do</code>, <code>try</code>, <code>catch</code>, <code>defer</code>, <code>throw</code>, <code>Error</code> &#x2014; even <code>NSError</code></a>, which also can be nastily nested, you truly get yourself into a major pyramid of doom. Note that my sample project has very little in the way of error checking, not to be sloppy, but so you can concentrate on the subject of this article without distraction.</p>



<p>Enter the Swift 5.5 <code>async</code>/<code>await</code> keywords, which by no means constitute <strong>all</strong> the new Swift concurrency features. I believe you should first learn about <code>async</code>/<code>await</code> before exploring the rest of Swift&#x2019;s new concurrency model.</p>



<h2 class="wp-block-heading">Good old GCD</h2>



<p>Let&#x2019;s start out talking about a tool that many of us have used in the past to perform long-running operations in the background, thus freeing our apps to do other things, and allowing the user interface (UI) to remain responsive. One common scenario is downloading a background image for an app&#x2019;s login screen while not preventing user interaction (like typing their username and password). Most of you should know about GCD, but if you don&#x2019;t, I&#x2019;ve written an extremely in-depth article on using it with Swift. In fact, the <a class="rank-math-link" href="http://iosbrain.com/blog/2018/03/07/concurrency-in-ios-serial-and-concurrent-queues-in-grand-central-dispatch-gcd-with-swift-4/?ref=appcoda.com">sample code</a> I discussed in that article is used right here.</p>



<p>Let&#x2019;s first read through my <code>downloadImageGCD</code> method, part of <a href="https://github.com/appcoda/Async-Await-Swift-Demo?ref=appcoda.com" class="rank-math-link">this article&#x2019;s companion project</a>. We&#x2019;ll talk about that function in just a minute:</p>



<pre class="wp-block-code"><code>...
// example of GCD asynchronous code; as
// soon as an image download is queued, control
// flows immediately onwards
func downloadImageGCD(for url: String, with index:Int) -&gt; Void {

    DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {

        _ = self.isCodeOnMainThread(named: &quot;start GCD image \(index) downloading...&quot;)
        let imageURL = URL(string: url)
        // this call blocks until the image data is downloaded,
        // BUT we&apos;re running in the background
        let imageData = NSData(contentsOf: imageURL!)
        // convert the data into an image
        let image = UIImage(data: imageData! as Data)

        DispatchQueue.main.async {
            self.imageViewStellar.image = image
            self.imageViewStellar.setNeedsDisplay()
            print(&quot;GCD image \(index) downloaded/displayed&quot;)
        }

    } // end DispatchQueue.global(qos: ...

} // end func downloadImageGCD
...</code></pre>



<p>By wrapping my GCD code in a <code>for</code> loop, the downloading of 22 big image files are queued up, but the downloads occur in the background, so the UI remains responsive, and I can click any of my sample app&#x2019;s buttons at any time and they do some concurrent work. The following <code>for</code> loop is called when you click the &#x201C;Start GCD Downloading&#x201D; button on the app&#x2019;s main screen:</p>



<pre class="wp-block-code"><code>...
func startGCDAsyncImageDownload()
{
    for index in 0..&lt;imageURLs.count
    {
        downloadImageGCD(for: imageURLs[index], with: index)
    }
} // end func startAsyncImageDownload()
...</code></pre>



<p>Watch the video of my app working and check out my <code>print</code> statements to the console. Notice there&#x2019;s a bit of stuttering when I click the &#x201C;Increment&#x201D; button, but that&#x2019;s mainly due to updating the <code>UIImageView</code> on the main thread:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="722" height="574" src="https://www.appcoda.com/content/images/wordpress/2021/07/GCD_download.gif" alt="Deep Dive into Swift 5.5&apos;s Async/await Concurrency Model" class="wp-image-19449"></figure>



<p>My <code>downloadImageGCD</code> function is intrinsically asynchronous. Given a URL, you schedule a task to download the data at that URL on a background thread. Then you specify a completion handler to display the downloaded data in a <code>UIImageView</code> and move on. Code flow whips right through this function. By the time the images start displaying in the UI, you can be off somewhere else in the app&#x2019;s code. <strong>REMEMBER: As shown above, <em>always</em> update your UI on the main thread.</strong> See my <code>updateImageView(with:)</code> used throughout the sample project.</p>



<p>Since I&#x2019;m running my code on a multi-core processor, calling <code>downloadImageGCD</code> demonstrates true parallelism. Concurrency/asynchrony involves a stochastic (random) element. Look at my console output to see the random queuing and completion of tasks &#x2014; and <a href="http://iosbrain.com/blog/2018/03/07/concurrency-in-ios-serial-and-concurrent-queues-in-grand-central-dispatch-gcd-with-swift-4/?ref=appcoda.com#cpuTool">go to Xcode&#x2019;s <em>Debug navigator</em> -&gt; <em>CPU</em> to see worker threads being created and eventually cleaned up</a>:</p>



<pre class="wp-block-code"><code>start GCD image 0 downloading... ON BACKGROUND THREAD
start GCD image 1 downloading... ON BACKGROUND THREAD
start GCD image 2 downloading... ON BACKGROUND THREAD
start GCD image 4 downloading... ON BACKGROUND THREAD
start GCD image 3 downloading... ON BACKGROUND THREAD
start GCD image 5 downloading... ON BACKGROUND THREAD
...
GCD image 9 downloaded/displayed
GCD image 21 downloaded/displayed
GCD image 7 downloaded/displayed
GCD image 18 downloaded/displayed
GCD image 12 downloaded/displayed
GCD image 5 downloaded/displayed</code></pre>



<p>I purposely used the <code>init(contentsOf:)</code> initializer of <code>NSData</code> to download image data because it is a synchronous, blocking call, a concept central to this article. Yes, it blocks until <strong>all</strong> data at the specified URL downloads, but I&#x2019;m using that <code>NSData</code> initializer on a <strong>background</strong> thread. If you called that function on your main thread, your app would freeze until all URL data downloads. Remember that I submitted the synchronous download inside a block passed to the very <strong>asynchronous</strong> <code>DispatchQueue...async {...}</code>. Later, we&#x2019;ll see that &#x201C;blocking&#x201D; or &#x201C;suspending&#x201D; have a different meaning in <code>async</code>/<code>await</code>.</p>



<p>The SDKs available to Swift have been populated with many, many calls that include completion handlers or delegate callbacks, not just <code>DispatchQueue</code>. I have a lot of good asynchronous code that&#x2019;s already been written using the <code>block</code>&#x2013;<code>completion handler</code> pattern. I&#x2019;m certainly not going to go back and rewrite it all using the new Swift concurrency gimmicks. But looking forward, I will consider using constructs like <code>async</code>/<code>await</code>.</p>



<h2 class="wp-block-heading">The Swift 5.5 async/await construct</h2>



<p>Let&#x2019;s define some terminology essential to understanding Swift&#x2019;s new concurrency model.</p>



<p><code>async</code>:</p>



<ul><li>add this keyword to a function signature (declaration) to denote that that method is asynchronous, i.e., can potentially run code in parallel with other code, and can be subject to suspension and later resumption</li><li>suspension may occur, for example, to await the results of some long-running task</li><li>suspension may occur, for example, for short-term tasks like updating the UI</li><li>suspension may not occur at all</li><li>functions marked <code>async</code> must themselves call <code>await</code> to be suspended (see below)</li><li>when an async function suspends, it does not block its thread</li><li>when an async function suspends, the operating system can queue and execute other processes on it&#x2019;s thread</li></ul>



<p><code>await</code>:</p>



<ul><li>obviously marks a potential suspension point in your code, making that suspension point clear to people reading the code</li><li>the code on the rest of the line following the <code>await</code> can be scheduled by the system for running a long task</li><li>that long task can be suspended once or many times so the system can execute other work</li><li>a shorter task might not be suspended at all and it can run to completion</li><li>once its task finishes, the <code>await</code> line finishes, and execution continues on the next line</li><li>when Swift suspends the current thread, other code is allowed to execute on that same thread</li></ul>



<p><code>async-let</code>:</p>



<ul><li>lets you call asynchronous functions when you don&#x2019;t need the return value immediately</li><li>you can start one or many tasks that can be run in parallel</li><li>other code can run while your asynchronous functions process</li></ul>



<p><code>async {...}</code>:</p>



<ul><li>enables you to kick off asynchronous work from within regular, synchronous code, like from within a function <strong>not</strong> labelled <code>async</code></li><li>you call your asynchronous code between the &#x201C;{&#x201D; and &#x201C;}&#x201D;</li></ul>



<h3 class="wp-block-heading">How to write code with async/await</h3>



<p>Now that we&#x2019;ve defined the terms <code>async</code> and <code>await</code> at a theoretical level, let&#x2019;s learn how to write code using these constructs. As an alternative to my <code>downloadImageGCD</code> method, which uses GCD with a completion handler, let&#x2019;s write an <code>async</code> function that you call with an image URL and it <strong>returns</strong> the image data, kind of like a synchronous function would do so. But it doesn&#x2019;t block, it possibly suspends for a relatively brief period while the image downloads, probably on a background thread, but that is not guaranteed as I understand the new Swift construct (see my definitions above).</p>



<pre class="wp-block-code"><code>...
func downloadImageAsync(for url: String, with index:Int) async throws -&gt; UIImage {

    _ = isCodeOnMainThread(named: &quot;start awaitable image \(index) downloading...&quot;)
    let request = URLRequest(url: URL(string: url)!)
    let (data, response) = try await URLSession.shared.data(for: request)
    guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw HTTPError.withIdentifier((response as! HTTPURLResponse).statusCode) }
    let downloadedImage = UIImage(data: data)
    return downloadedImage!

} // end func downloadImageAsync
...</code></pre>



<p>Notice that we place the <code>async</code> keyword just after the method signature&#x2019;s parameter list but before the <code>throws</code> and the return type. Pause for a moment to review my <code>async</code> keyword definition up above.</p>



<p>The key to this method is this line:</p>



<pre class="wp-block-code"><code>    let (data, response) = try await URLSession.shared.data(for: request)</code></pre>



<p>Since <code>URLSession.shared.data</code> is <code>async</code> (&#x201C;awaitable&#x201D;), we <em>must</em> call it with <code>await</code>; it also <code>throws</code>. If an <code>async</code> function <code>throws</code>, you always put a <code>try</code> before the <code>await</code>, as we did here when calling the function. The lines of code both before and after <code>data(for:)</code> on the shared URLSession are synchronous. The code after this network download call is dependent on the <code>data</code> and <code>response</code> it returns, so it must suspend while the image data at <code>url</code> downloads. Here&#x2019;s the magic: while this line (and its containing method) suspend, <strong>other work in the app can be done.</strong></p>



<p>A great benefit of writing code with <code>async</code>/<code>await</code> is the enhanced readability. You can obviously see asynchronous code and potential suspension points. There&#x2019;s also less clutter without the closure syntax.</p>



<h3 class="wp-block-heading">Our first try at async/await</h3>



<p>To prove to you that <code>async</code>/<code>await</code> works efficiently and allows other app work to be done simultaneously, let&#x2019;s do an experiment with my code. I&#x2019;ve got some code commented out, but don&#x2019;t make any changes yet. Let&#x2019;s review what you&#x2019;ll do first. Here&#x2019;s the code that my app&#x2019;s &#x201C;Start Proper Awaitable Downloading&#x201D; button calls:</p>



<pre class="wp-block-code"><code>...
@IBAction func startProperAwaitableDownloadingButtonClicked(_ sender: Any) {

    counter = 0;
    counterTextField.text = &quot;0&quot;
    imageViewStellar.image = nil

    async {

        let image = try! await downloadImageAsync(for: imageAltURLs[0], with: 0)
        updateImageView(with: image)
        print(&quot;GIANT FILE FINALLY DOWNLOADED&quot;)
        //await startRightNewSimpleSyncImageDownload()
        //await startRightNewSimpleAsyncImageDownload()
        //await startExperimentAsyncImageDownload()
        //await startTaskGroupAsyncImageDownload()
    }

} // end startProperAwaitableDownloadingButtonClicked
...</code></pre>



<p>While this <code>@IBAction func</code> is synchronous, note that you can call <code>async</code> code by wrapping it in the <code>async{...}</code> construct as defined above. The image at the URL in <code>imageAltURLs[0]</code> is gigantic and takes awhile to download. You already saw earlier that my <code>downloadImageGCD</code> function downloads and displays 22 large image files. Ready? Run my app and press the &#x201C;Start Proper Awaitable Downloading&#x201D; button, then quickly press the &#x201C;Start GCD Downloading&#x201D; button.</p>



<p>Your console output should be similar to that shown next, though not exactly the same. You&#x2019;ll see the <code>async</code> call to download the huge file start up and suspend. Then you&#x2019;ll see the GCD function simultaneously queuing and downloading 22 images. Most of the time, the <code>async</code> file will download later to last when considering all total 23 downloads, not because there&#x2019;s anything wrong with <code>async</code>, but because it&#x2019;s downloading a very large file.</p>



<pre class="wp-block-code"><code>start awaitable image 0 downloading... ON MAIN THREAD
start GCD image 0 downloading... ON BACKGROUND THREAD
start GCD image 1 downloading... ON BACKGROUND THREAD
start GCD image 2 downloading... ON BACKGROUND THREAD
start GCD image 3 downloading... ON BACKGROUND THREAD
...
start GCD image 19 downloading... ON BACKGROUND THREAD
start GCD image 21 downloading... ON BACKGROUND THREAD
start GCD image 20 downloading... ON BACKGROUND THREAD
GCD image 0 downloaded/displayed
GCD image 4 downloaded/displayed
GCD image 2 downloaded/displayed
...
GCD image 20 downloaded/displayed
GCD image 21 downloaded/displayed
GCD image 16 downloaded/displayed
GIANT FILE FINALLY DOWNLOADED</code></pre>



<h2 class="wp-block-heading">How NOT to use async/await</h2>



<p>Unless you&#x2019;re enforcing some specific order of execution because of certain interdependencies, I would advise you to avoid using a bunch of <code>await</code> calls in sequence. Let&#x2019;s look at two examples from my project. Here&#x2019;s a &#x201C;manual&#x201D; example:</p>



<pre class="wp-block-code"><code>...
// these downloads occur SEQUENTIALLY because we
// start each download with the &quot;await&quot; keyword
func startRightNewSimpleSyncImageDownload() async -&gt; Void {

    let stellarImage0 = try! await downloadImageAsync(for: imageURLs[0], with: 0)
    let stellarImage1 = try! await downloadImageAsync(for: imageURLs[1], with: 1)
    let stellarImage2 = try! await downloadImageAsync(for: imageURLs[2], with: 2)

    _ = isCodeOnMainThread(named: &quot;startRightNewAsyncImageDownload&quot;)

    // no await is needed
    updateImageView(with: stellarImage0)
    print(&quot;stellarImage0 with index 0 downloaded&quot;)
    updateImageView(with: stellarImage1)
    print(&quot;stellarImage1 with index 1 downloaded&quot;)
    updateImageView(with: stellarImage2)
    print(&quot;stellarImage2 with index 2 downloaded&quot;)

} // end func startRightNewSimpleSyncImageDownload
...</code></pre>



<p>Here&#x2019;s a &#x201C;automated&#x201D; example (I used a <code>for</code> loop):</p>



<pre class="wp-block-code"><code>...
// this method is a misguided attempt to
// call a bunch of blocking calls all at once
func startWrongNewAsyncImageDownload()
{

    async {

        for index in 0..&lt;imageURLs.count {
            let url = imageURLs[index]
            let downloadedImage = try! await self.downloadImageAsync(for: url, with: index)
            imageViewStellar.image = downloadedImage
            print(&quot;awaitable image \(index) downloaded/displayed&quot;)
        }

    } // end async

} // end func startWrongNewAsyncImageDownload()
...</code></pre>



<p>Why would I impose such a sequential ordering, especially if I were preparing an image gallery and/or the thumbnails for a <code>UICollectionView</code>? Even with concurrency involved, think of what would happen if each of the image downloads was in the order of 170 MB, as opposed to the ~30 MB files I&#x2019;m downloading from my URL array&#x2019;s addresses. Or suppose I had a long list of mathematically intense calculations? I&#x2019;d have a lot of uninterruptible tasks that would make my app run sluggishly at best. Even if I were required to enforce a sequence of tasks, each dependent on the previous one, this wouldn&#x2019;t be the most optimal way to encode my work. See the console output:</p>



<pre class="wp-block-code"><code>start awaitable image 0 downloading... ON MAIN THREAD
awaitable image 0 downloaded/displayed
start awaitable image 1 downloading... ON MAIN THREAD
awaitable image 1 downloaded/displayed
start awaitable image 2 downloading... ON MAIN THREAD
awaitable image 2 downloaded/displayed
start awaitable image 3 downloading... ON MAIN THREAD
awaitable image 3 downloaded/displayed
start awaitable image 4 downloading... ON MAIN THREAD
awaitable image 4 downloaded/displayed
start awaitable image 5 downloading... ON MAIN THREAD
awaitable image 5 downloaded/displayed
start awaitable image 6 downloading... ON MAIN THREAD
awaitable image 6 downloaded/displayed
start awaitable image 7 downloading... ON MAIN THREAD
awaitable image 7 downloaded/displayed
start awaitable image 8 downloading... ON MAIN THREAD
awaitable image 8 downloaded/displayed
start awaitable image 9 downloading... ON MAIN THREAD
awaitable image 9 downloaded/displayed
start awaitable image 10 downloading... ON MAIN THREAD
awaitable image 10 downloaded/displayed
start awaitable image 11 downloading... ON MAIN THREAD
awaitable image 11 downloaded/displayed
start awaitable image 12 downloading... ON MAIN THREAD
awaitable image 12 downloaded/displayed
start awaitable image 13 downloading... ON MAIN THREAD
awaitable image 13 downloaded/displayed
start awaitable image 14 downloading... ON MAIN THREAD
awaitable image 14 downloaded/displayed
start awaitable image 15 downloading... ON MAIN THREAD
awaitable image 15 downloaded/displayed
start awaitable image 16 downloading... ON MAIN THREAD
awaitable image 16 downloaded/displayed
start awaitable image 17 downloading... ON MAIN THREAD
awaitable image 17 downloaded/displayed
start awaitable image 18 downloading... ON MAIN THREAD
awaitable image 18 downloaded/displayed
start awaitable image 19 downloading... ON MAIN THREAD
awaitable image 19 downloaded/displayed
start awaitable image 20 downloading... ON MAIN THREAD
awaitable image 20 downloaded/displayed
start awaitable image 21 downloading... ON MAIN THREAD
awaitable image 21 downloaded/displayed</code></pre>



<p>As we&#x2019;ll see below, I can use <code>async</code>/<code>await</code> to download a whole bunch of images in parallel/simultaneously.</p>



<h2 class="wp-block-heading">Running multiple parallel tasks with async/await</h2>



<p>I always try to learn a new technology myself instead of waiting for someone else to figure it out and then doing copy and paste programming. I like to actually work through a practice test before looking at the answers in the back of the book. I want to figure out <em>why</em> I got some answers wrong.</p>



<p>Such was the case with figuring out how to run multiple parallel tasks with <code>async</code>/<code>await</code>. I was able to figure out how to manually use <code>async-let</code>. When I say &#x201C;manually,&#x201D; I mean I could start a fixed number of tasks, but couldn&#x2019;t figure out how generalize my code for some varying number of tasks. I think the problem with <code>async-let</code> is that the construct has a <code>let</code>, implying a constant, not a variable.</p>



<p>Here&#x2019;s my successful attempt at spawning 3 image downloads in parallel &#x2014; and displaying the images from the downloaded data:</p>



<pre class="wp-block-code"><code>...
// each download occurs asynchronously -- even simultaneously
func startRightNewSimpleAsyncImageDownload() async -&gt; Void {

    async let stellarImage0 = try! downloadImageAsync(for: imageURLs[0], with: 0)
    async let stellarImage1 = try! downloadImageAsync(for: imageURLs[1], with: 1)
    async let stellarImage2 = try! downloadImageAsync(for: imageURLs[2], with: 2)

    _ = isCodeOnMainThread(named: &quot;startRightNewAsyncImageDownload&quot;)

    updateImageView(with: await stellarImage0)
    print(&quot;stellarImage0 with index 0 downloaded&quot;)
    updateImageView(with: await stellarImage1)
    print(&quot;stellarImage1 with index 1 downloaded&quot;)
    updateImageView(with: await stellarImage2)
    print(&quot;stellarImage2 with index 2 downloaded&quot;)

} // end func startRightNewSimpleAsyncImageDownload
...</code></pre>



<p>OK, this works, but it is way too specific of a solution. What if I wanted to be able to download 2, 10, 30, or 60 images using some kind of repetitive language construct, like <code>for</code> or <code>while</code>? I tried to figure this repetitive thing out for awhile &#x2014; without looking for somebody else&#x2019;s solution. Look at my <code>startExperimentAsyncImageDownload()</code> function for evidence of my failed attempts.</p>



<h2 class="wp-block-heading">Using a TaskGroup with async/await</h2>



<p>In an effort to find a repetitive solution to downloading any number of images, I did some research. All&#x2019;s I found was a <a href="https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html?ref=appcoda.com#ID642">brief section in some Swift documentation</a> with a theoretical and not really usable solution. But I did get something working. Look at my sample code for a method named <code>startTaskGroupAsyncImageDownload()</code>, study it, run it, look at the console output, and watch my sample app&#x2019;s screen while the function is working. Here&#x2019;s the code:</p>



<pre class="wp-block-code"><code>...
// new Swift structured concurrency using
// tasks and task groups
func startTaskGroupAsyncImageDownload() async -&gt; Void {

    _ = self.isCodeOnMainThread(named: &quot;startRightNewAsyncImageDownload started&quot;)

    await withTaskGroup(of: UIImage.self) { taskGroup in

        for index in 0..&lt;imageURLs.count {
            taskGroup.async {
                //_ = await self.isCodeOnMainThread(named: &quot;task for image \(index) downloading started...&quot;)
                let downloadedImage = try! await self.downloadImageAsync(for: self.imageURLs[index], with: index)
                return downloadedImage
            }
        }

        // &quot;To collect the results of tasks that
        // were added to the group, you can use
        // the following pattern:&quot;
        for await image in taskGroup {
            _ = self.isCodeOnMainThread(named: &quot;task awaited image downloaded&quot;)
            // notice I didn&apos;t have to jump
            // on the main queue to update the UI
            self.imageViewStellar.image = image
            print(&quot;task awaited image displayed&quot;)
            // DispatchQueue.main.async {
            //      self.imageViewStellar.image = downloadedImage
            // }
        }

    } // end withTaskGroup

} // end func startTaskGroupAsyncImageDownload()
...</code></pre>



<p>Now this code acts truly concurrent. Hey, wait a minute. We&#x2019;re using a <em>closure</em>. Hmmm&#x2026;</p>



<p>I&#x2019;m not going into a detailed explanation of this method as the main purpose of this article is introducing readers to <code>async</code>/<code>await</code>. But let me share one insight. See my comment above this line of code?</p>



<pre class="wp-block-code"><code>        for await image in taskGroup {</code></pre>



<p>This was key to figuring out how to make my experimental code work. I found this <strong>not</strong> on the Swift website, but in the Xcode context sensitive help when I clicked on the <code>withTaskGroup</code> keyword:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>To collect the results of tasks that were added to the group, you can use the following pattern: &#x2026;</p></blockquote>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Understanding Swift 5.5&#x2019;s new concurrency features starts with <code>async</code>/<code>await</code>. I hope you learned a lot here today. I encourage you to practice using <code>async</code>/<code>await</code> with my sample code, study the links I&#x2019;ve included in this article, and then to push forward through all the WWDC 2021 presentations on Swift&#x2019;s other new concurrency features, like on actors, continuations, the <code>AsyncSequence</code> protocol, the <code>TaskGroup</code> generic structure, task cancellation, and a few other concepts. I especially recommend the WWDC 2021 sessions on <a class="rank-math-link" href="https://developer.apple.com/videos/play/wwdc2021/10134?ref=appcoda.com">&#x201C;Explore structured concurrency in Swift&#x201D;</a>, <a class="rank-math-link" href="https://developer.apple.com/videos/play/wwdc2021/10133?ref=appcoda.com">&#x201C;Protect mutable state with Swift actors&#x201D;</a>, and <a class="rank-math-link" href="https://developer.apple.com/videos/play/wwdc2021/10254?ref=appcoda.com">&#x201C;Swift concurrency: Behind the scenes&#x201D;</a>.</p>



<p><strong>One bit of homework:</strong> Look at my sample code&#x2019;s <code>isCodeOnMainThread(named:)</code> function. Can you explain why the function prints &#x201C;&#x2026;ON MAIN THREAD&#x201D; in some places while &#x201C;&#x2026;ON BACKGROUND THREAD&#x201D; in others? I&#x2019;m sure the <code>Thread.isMainThread</code> is working properly. I&#x2019;ll respond to any comments left on my article regarding this question, or respond to any other comments you may have.</p>



<p>Enjoy!</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Deploying Mac Apps Outside App Store: How to Remember User Intent for Folders]]></title><description><![CDATA[<!--kg-card-begin: html-->

<p>When a macOS user specifically grants a <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH1-SW1">sandboxed</a> app access to a file/folder <strong>outside</strong> of that app&#x2019;s <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW6">container</a>, that special access only survives until the app is closed. If the user reopens the app and wants to again read from and write to that &#x201C;outside&#x201D;</p>]]></description><link>https://www.appcoda.com/mac-apps-user-intent/</link><guid isPermaLink="false">66612a0f166d3c03cf0114db</guid><category><![CDATA[macOS programming]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Thu, 27 Aug 2020 10:42:11 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2020/08/rhvd9wlno_i.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->

<img src="https://www.appcoda.com/content/images/wordpress/2020/08/rhvd9wlno_i.jpg" alt="Deploying Mac Apps Outside App Store: How to Remember User Intent for Folders"><p>When a macOS user specifically grants a <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH1-SW1">sandboxed</a> app access to a file/folder <strong>outside</strong> of that app&#x2019;s <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW6">container</a>, that special access only survives until the app is closed. If the user reopens the app and wants to again read from and write to that &#x201C;outside&#x201D; folder, they have to go through the whole process of showing macOS their &#x201C;intent&#x201D; to stray out of the container &#x2014; unless the developer adds something called &#x201C;security-scoped bookmarks.&#x201D; These bookmarks are the topic of today&#x2019;s tutorial.</p>



<p>I&#x2019;ll be explaining in-depth how developers can create these special bookmarks, store them, access them later, including two <strong>required</strong> steps that must take place just before and just after a stored bookmark is referenced. Specifically, I&#x2019;ll be clarifying Apple&#x2019;s rather terse documentation on <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW16">&#x201C;the methods, constants, and entitlements to use for implementing security-scoped bookmarks in your app.&#x201D;</a></p>



<p>Please <a href="https://github.com/appcoda/MacSandboxDemo/blob/master/part4demo.zip?ref=appcoda.com" class="rank-math-link">download my sample Xcode 11.6 project</a>, written in Swift, essential for getting the most out of this tutorial.</p>



<h2 class="wp-block-heading">A series of tutorials</h2>



<p>This is the fourth part in a four-part series of tutorials comparing the differences between distributing macOS apps inside and outside of the Mac App Store (MAS), comparing sandboxed and non-sandboxed apps, and considering app security.</p>



<p>In <a href="https://www.appcoda.com/distribute-macos-apps/">Part I of this series</a>, I built a non-sandboxed app, discussed certificates, signed the app, notarized it, briefly talked about building an installer, signed and notarized the installer, and lastly touched on distribution of the app installer.</p>



<p>In <a href="https://www.appcoda.com/mac-app-sandbox/">my second tutorial (Part II)</a>, I examined the app sandbox and then built an app that, whether sandboxed or not sandboxed, could read and write outside of its container &#x2014; and could be sold and distributed either outside the MAS or through the MAS, both with Apple&#x2019;s blessings.</p>



<p><a href="https://www.appcoda.com/packages-macos-apps-distribution/">Part III</a> was my detailed guide on how to use Packages, by far one of the most popular macOS development tools, for creating app installers, allowing you too securely distribute your products and help your customers easily add your functionality to their Macs. You can review <a href="https://www.appcoda.com/author/andrewjaffee/">my column here on AppCoda</a> for a list of all four parts of my series, as well as all my other articles.</p>



<h2 class="wp-block-heading">Review of app sandboxing</h2>



<p>My Part II article has a detailed definition of sandboxing in the section entitled <a href="https://www.appcoda.com/mac-app-sandbox/#What_is_an_app_sandbox">&#x201C;What is an app sandbox?&#x201D;</a>. Please review, but let me briefly explain how today&#x2019;s tutorial gives you additional control over sandbox restrictions.</p>



<p>You should think of the sandbox as a very constrictive fence surrounding your app. Of course, an app would be useless if this fence was impenetrable. Apps are only useful if they can act on some type of input and produce meaningful output. Apple wants us as developers to start with very little access to system resources and then only request more resources on an <strong>as-needed</strong> basis. Because of scope, time, and space constraints, I&#x2019;ve confined the discussion of resources to the file system, but keep in mind that your vulnerable surface area includes Mac components like network connections, microphones, the camera, Bluetooth, etc. To reiterate, in this tutorial, we&#x2019;re going to &#x201C;bookmark&#x201D; a resource &#x2014; a folder&#x2019;s URL &#x2014; <strong>outside</strong> the sandbox so the user doesn&#x2019;t have to approve access to that folder every time he/she opens the app.</p>



<p>To keep this article focused on one topic, let me just be precise in my terminology. There are actually <strong>two types of security-scoped bookmarks</strong>. Using Apple&#x2019;s language, we&#x2019;ll only be talking about an <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW19">app-scoped bookmark</a>, one which &#x201C;provides your sandboxed app with persistent access to a user-specified file or folder.&#x201D; The other type, a document-scoped bookmark, is similar but slightly more complex and &#x201C;typically supports the notion of a project document that refers to other files.&#x201D; I leave it to you to do some research and easily extrapolate from the knowledge provided in this tutorial.</p>



<h2 class="wp-block-heading">Review of getting user intent for folders outside the sandbox</h2>



<p>If a user wants to access a file/folder that is <strong>outside</strong> of the container, Apple <strong>requires</strong> the user to explicitly select that file/folder using an <code>NSOpenPanel</code>. Apple is getting the user&#x2019;s overt permission &#x2014; they call &#x201C;intent&#x201D; &#x2014; to access that folder/file. This is one of Apple&#x2019;s methods for limiting the vulnerable surface area of the app to attack by malware. Remember that no permission is needed from the user to access the file system inside the app&#x2019;s sandboxed container.</p>



<p>Configuring and implementing this intent-getting feature requires some preparation via Xcode which is discussed in detail in Part II of this series. Please review the section in that article entitled <a href="https://www.appcoda.com/mac-app-sandbox/#Persistent_access_outside_of_the_sandbox">&#x201C;Getting user intent for folders outside the sandbox.&#x201D;</a> We&#x2019;ll review the code shown in that section again as <strong>a slightly modified version of it is also incorporated into the source included with this tutorial&#x2019;s <a href="https://github.com/appcoda/MacSandboxDemo/blob/master/part4demo.zip?ref=appcoda.com" class="rank-math-link">sample project</a></strong>.</p>



<p>I determine the user&#x2019;s &#x201C;intent&#x201D; by running my app, clicking my <em>Select folder</em> button, and recording the URL of the folder the user picked (<code>~/Documents</code>). What I&#x2019;m doing is saying &#x201C;If you want to access a folder <strong>outside</strong> of the container, you have to <strong>explicitly</strong> tell me it&#x2019;s OK for the app to read and/or write there.&#x201D; When you look at my sample source code for <strong>this tutorial</strong>, you&#x2019;ll notice some new code I&#x2019;ve added to the function in which user intent for a folder (and its URL) is obtained: I create a security-scoped bookmark for that folder/URL. Here&#x2019;s a short video showing how my app gets the user&#x2019;s permission to access their Mac&#x2019;s <code>~/Documents</code> folder and then creates a security-scoped bookmark for that folder:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="954" height="576" src="https://www.appcoda.com/content/images/wordpress/2020/08/showUserIntent.gif" alt="Deploying Mac Apps Outside App Store: How to Remember User Intent for Folders" class="wp-image-18603"></figure>



<p>This would be a really good time for you to open up my sample project and start following along.</p>



<h2 class="wp-block-heading">Implementing security-scoped bookmarks</h2>



<p>Let&#x2019;s discuss my code so you can implement security-scoped bookmarks in your own macOS apps. I&#x2019;ve placed some step numbers (e.g., &#x201C;STEP 1&#x201D;) in my source commentary that will make it easier for us to talk about my code here in the tutorial while also easily being able to find it in my project.</p>



<h3 class="wp-block-heading">Project configuration</h3>



<p>I&#x2019;ve mentioned &#x201C;Step 1&#x201D; in my code just as a reminder, but it is an Xcode project configuration option. Open the project&#x2019;s <code>AppNotaryAndDistrib.entitlements</code> file and make sure you take notice of <strong>1)</strong> the entitlement turning on sandboxing and <strong>2)</strong> the entitlement enabling security-scoped bookmarks, like so:</p>



<pre class="wp-block-code"><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;dict&gt;
    &lt;key&gt;com.apple.security.app-sandbox&lt;/key&gt;
    &lt;true/&gt;
    &lt;key&gt;com.apple.security.files.user-selected.read-write&lt;/key&gt;
    &lt;true/&gt;
    &lt;key&gt;com.apple.security.files.bookmarks.app-scope&lt;/key&gt;
    &lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;</code></pre>



<h3 class="wp-block-heading">Selecting a folder to bookmark</h3>



<p>Now let&#x2019;s dive into my Swift. Look at the <code>selectFolderBtnClicked(_ sender: Any)</code> method in my sample project&#x2019;s <code>ViewController.swift</code> file:</p>



<pre class="wp-block-code"><code>...
/**
 We encourage the user to select a folder, like ~/Documents,
 showing their &quot;intent&quot; to grant our app access to that folder.
 That directory is OUTSIDE of this app&apos;s sandbox. We do this
 in preparation for allowing us to reach out of our container. What&apos;s
 new in this version of the code is BOOKMARKING the selected folder.
*/
@IBAction func selectFolderBtnClicked(_ sender: Any) {

    self.pathTextField.stringValue = &quot;...&quot;

    let folderSelectionDialog = NSOpenPanel() // a modal dialog

    folderSelectionDialog.prompt = &quot;Select&quot;
    folderSelectionDialog.message = &quot;Please select a folder&quot;

    folderSelectionDialog.canChooseFiles = false
    folderSelectionDialog.allowedFileTypes = [&quot;N/A&quot;]
    folderSelectionDialog.allowsOtherFileTypes = false

    folderSelectionDialog.allowsMultipleSelection = false

    folderSelectionDialog.canChooseDirectories = true

    // open the MODAL folder selection panel/dialog
    let dialogButtonPressed = folderSelectionDialog.runModal()

    // if the user pressed the &quot;Select&quot; (affirmative or &quot;OK&quot;)
    // button, then they&apos;ve chosen a folder
    if dialogButtonPressed == NSApplication.ModalResponse.OK {

        if folderSelectionDialog.urls.count == 1 {

            if let url = folderSelectionDialog.urls.first {

                // if the user doesn&apos;t select anything, then
                // the URL &quot;file:///&quot; is returned, which we ignore
                if url.absoluteString != &quot;file:///&quot; {

                    // save the user&apos;s selection so that we can
                    // access the folder they specified later
                    self.userSelectedFolderURL = url

                    print(&quot;User selected folder: \(url)&quot;)
                    self.pathTextField.stringValue = url.absoluteString

                    // STEP 1 - add the entitlement to our target notifying
                    // macOS that we&apos;re using security-scoped bookmarks

                    // STEP 2 - create a persistent bookmark for the
                    // folder the user just selected
                    _ = saveBookmarkForSelectedURL()

                } else {
                    print(&quot;User did not select a folder: file:///&quot;)
                }

            } // end if let url = folderSelectionDialog.urls.first {

        } else {

            print(&quot;User did not select a folder&quot;)

        } // end if folderSelectionDialog.urls.count

    } else if dialogButtonPressed == NSApplication.ModalResponse.cancel { // user clicked on &quot;Cancel&quot;

        print(&quot;User cancelled folder selection panel&quot;)

    } // end if dialogButtonPressed == NSApplication.ModalResponse.OK

} // end func selectFolderBtnClicked
...</code></pre>



<p>What I&#x2019;m doing in here is popping up an <code>NSOpenPanel</code>, allowing the user to browse through their Mac&#x2019;s file system, and enabling him/her to select a folder outside the sandbox. There&#x2019;s one important difference between the <a href="https://www.appcoda.com/mac-app-sandbox/#Getting_user_intent_for_folders_outside_the_sandbox">Part II</a> code and that shown immediately above: Once I obtain the URL of the folder for which the user has clearly shown their intent, I <strong>bookmark</strong> that folder. By doing this, the app remembers the folder so the user doesn&#x2019;t have to go through all the rigamarole required to give permission to access that folder every time the app is run. Remember that I showed you a video up above of this process.</p>



<p>It might be a good idea to provide a checkbox in an <a href="https://developer.apple.com/documentation/appkit/nssavepanel/1525544-accessoryview?ref=appcoda.com"><code>accessoryView</code></a> you wire into your <code>NSOpenPanel</code> with a prompt saying something like &#x201C;Remember this folder?&#x201D; This would provide a higher level of security by requiring your users to decide whether a folder outside the container should remain accessible &#x201C;forever&#x201D; or not. That&#x2019;s a style issue I leave to you. Note that <code>NSOpenPanel</code> inherits from <code>NSSavePanel</code>.</p>



<h3 class="wp-block-heading">Bookmarking a folder outside the container</h3>



<p>Let&#x2019;s continue talking about my <code>selectFolderBtnClicked(_ sender: Any)</code> method, but concentrate on the new bookmarking code. In an effort help developers understand my code, I added a project configuration reminder: &#x201C;STEP 1 &#x2013; add the entitlement to our target notifying macOS that we&#x2019;re using security-scoped bookmarks.&#x201D; In other words, don&#x2019;t forget to add the <code>com.apple.security.files.bookmarks.app-scope</code> entitlement before doing anything else. STEP 2 is the call to my <code>saveBookmarkForSelectedURL()</code> method. There, I create a persistent bookmark for the folder/URL the user just selected. I pass the URL to the <a href="https://developer.apple.com/documentation/foundation/nsurl/1417795-bookmarkdata?ref=appcoda.com"><code>bookmarkData(options:includingResourceValuesForKeys:relativeTo:)</code></a> instance method of the <code>NSURL</code> class (STEP 2.1) and then save the new bookmark in <code>UserDefaults</code> (STEP 2.2). The bookmark is some kind of <code>Data</code> blob (with metadata?), most likely encrypted so that malicious software with prying eyes can&#x2019;t read it from a preferences <code>.plist</code> file. Remember to store the bookmark data value in preferences with a meaningfully-named key:</p>



<pre class="wp-block-code"><code>...
func saveBookmarkForSelectedURL() -&gt; Bool {

    do {

        if let selectedURL = self.userSelectedFolderURL {

            // STEP 2.1 - create a security-scoped bookmark
            // &quot;Returns bookmark data for the URL, created with specified options and resource values.&quot;
            // Return Value: Type: Data - A bookmark for the URL.
            let bookmarkData = try selectedURL.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)

            // get an instance of UserDefaults
            let userDefaults = UserDefaults.standard

            // STEP 2.2 - store the newly-created bookmark in UserDefaults
            // accessible with a meaningful key; user defaults supports storing
            // and fetching the Data/NSData types
            userDefaults.set(bookmarkData, forKey: &quot;PermanentFolderBookmark&quot;)

            // creating the bookmark did not throw an error, so return positive
            return true

        } else {
            print(&quot;ERROR: You cannot bookmark a URL that is nil&quot;)
            return false
        }

    } catch let error {

        print(&quot;Could not create a bookmark because: &quot;, error)
        return false

    }

} // end func saveBookmarkForSelectedURL()
...</code></pre>



<h3 class="wp-block-heading">Retrieving a bookmarked folder/URL</h3>



<p>Now we&#x2019;ll see how a security-scoped bookmark lasts across app launches. Let&#x2019;s assume that the user of my app has explicitly used the <em>Select folder</em> button in my app&#x2019;s UI, thus executing my <code>selectFolderBtnClicked(_ sender: Any)</code> method, and added the <code>~/Documents</code> folder to their app sandbox as we just finished discussing. Let&#x2019;s further assume that the user closed my app after bookmarking <code>~/Documents</code> and it is now 5 days later. They launch my app and then click the <em>Write to file</em> button. The <code>IBAction</code> bound to that button, <code>writeToFileBtnClicked(_ sender: Any)</code>, is shown below, but in this section we&#x2019;ll only talk about STEP 3.</p>



<p>Getting the bookmark stored in <code>UserDefaults</code> is a whole step in and of itself. Accessing &#x2014; reading from or writing to &#x2014; the bookmark/URL takes some special handling that we&#x2019;ll talk about separately. We&#x2019;ll talk about STEP 4, STEP 5, and STEP 6 in the next section.</p>



<p>Read through the following code and take special notice of STEP 3, the call to <code>getPersistentFileURL()</code>. We&#x2019;ll talk about that method just below the code for <code>writeToFileBtnClicked(_ sender: Any)</code>.</p>



<pre class="wp-block-code"><code>...
@IBAction func writeToFileBtnClicked(_ sender: Any) {

    self.pathTextField.stringValue = &quot;...&quot;

    // STEP 3 - get the permanent folder location the user selected earlier
    if var persistentURL = getPersistentFileURL() {

        // STEP 4 - &quot;Explicitly indicate that you want to use the file-system resource whose URL you obtained in step 3. Do this immediately after obtaining the security-scoped URL...&quot;
        _ = persistentURL.startAccessingSecurityScopedResource()

        // create the FULLY-QUALIFIED path to the file by
        // appending a file name to the URL (path)
        persistentURL = persistentURL.appendingPathComponent(&quot;test.txt&quot;, isDirectory: false)
        print(&quot;Persistent URL: &quot;, persistentURL)

        // STEP 5 - prepare text to write to the file
        let fileText = &quot;This is the text in the file.&quot;;

        // try writing file to a non-sandboxed folder...
        do {
            try fileText.write(to: persistentURL, atomically: false, encoding: String.Encoding.utf8)
            self.pathTextField.stringValue = persistentURL.absoluteString
        }
        catch let error // ... or find out why write fails
        {
            print(error.localizedDescription)
            // write some code to recover from error
        }

        // STEP 6 - &quot;When done using the resource, explicitly indicate that you want to stop using it. Do this as soon as you know that you no longer need access to the resource (typically, after you close it).&quot;
        persistentURL.stopAccessingSecurityScopedResource()

    } // end if var persistentURL = ...

} // end func writeToFileBtnClicked
...</code></pre>



<p>STEP 3 is the call to <code>getPersistentFileURL()</code> which returns our previously-bookmarked URL. To get our bookmark, first we need to retrieve the bookmark&#x2019;s <code>Data</code> value from <code>UserDefaults</code> by using the key with which we originally saved it. In STEP 3.1, we extract the URL from our bookmark&#x2019;s <code>Data</code> by passing that blob to <a href="https://developer.apple.com/documentation/foundation/nsurl/1413475-init?ref=appcoda.com"><code>init(resolvingBookmarkData:options:relativeTo:bookmarkDataIsStale:)</code></a>, an initializer of <code>NSURL</code>. It&#x2019;s pretty obvious that we want a URL from our stored bookmark, so there&#x2019;s no need to dissect this SDK method call. The only thing I&#x2019;ll highlight is the <code>bookmarkDataIsStale</code> variable that I pass as a pointer into the <code>resolvingBookmarkData</code> initializer. If an app gets deleted and reinstalled, macOS is upgraded, or some such unforeseen eventuality occurs, it&#x2019;s possible that our bookmark may be wrong or outdated. We certainly don&#x2019;t want a URL that points to garbage or <code>nil</code>, thus you see the code I&#x2019;ve written to handle a &#x201C;stale&#x201D; bookmark in STEP 3.2. When <code>getPersistentFileURL()</code> returns, STEP 3 is done, and we&#x2019;ve got our URL from our bookmark. Please go back up and review my <code>writeToFileBtnClicked(_ sender: Any)</code> method up above and we&#x2019;ll pick up in the next section with STEP 4.</p>



<pre class="wp-block-code"><code>...
func getPersistentFileURL() -&gt; URL? {

    // STEP 3 - get the permanent folder location the user selected earlier
    // get from UserDefaults
    let userDefaults = UserDefaults.standard
    if let bookmarkData = userDefaults.data(forKey: &quot;PermanentFolderBookmark&quot;) {

        do {

            // we&apos;ll pass this variable by value so it can be set
            // by an SDK method
            var bookmarkDataIsStale = false
            // STEP 3.1 - &quot;When you later need access to a bookmarked resource, resolve its security-scoped bookmark by calling the the URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error: method of the NSURL class&quot;
            let urlForBookmark = try URL(resolvingBookmarkData: bookmarkData, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &amp;bookmarkDataIsStale)

            // STEP 3.2 - a bookmarks might be &quot;stale&quot; because the app hasn&apos;t been used
            // in many months, macOS has been upgraded, the app was
            // re-installed, the app&apos;s preferences .plist file was deleted, etc.
            if bookmarkDataIsStale {
                print(&quot;The bookmark is outdated and needs to be regenerated.&quot;)
                _ = saveBookmarkForSelectedURL()
                return nil

            } else {
                return urlForBookmark
            }

        } catch {
            print(&quot;Error resolving bookmark:&quot;, error)
            return nil
        }

    } else { // bookmarkData is nil

        print(&quot;Error retrieving persistent bookmark data.&quot;)
        return nil

    } // end if let bookmarkData =

} // end getPersistentFileURL
...</code></pre>



<h3 class="wp-block-heading">Accessing a bookmarked folder/URL</h3>



<p>Let&#x2019;s pick up where we left off in my <code>writeToFileBtnClicked(_ sender: Any)</code> method up above. Remember we took a short detour to examine how a URL is obtained from bookmark <code>Data</code> stored in <code>UserDefaults</code>. Let&#x2019;s assume have our URL and resume our discussion with STEP 4. You cannot read from or write to a resolved bookmark&#x2019;s URL directly. We&#x2019;ll be writing a file to our bookmark folder&#x2019;s URL in this case. Apple requires a special step both <strong>before</strong> and <strong>after</strong> we write (well, access in general).</p>



<p>I believe there is sound method in Apple&#x2019;s madness. They want <strong>developers</strong> to be absolutely certain they know that they&#x2019;re potentially accessing a file/folder that&#x2019;s &#x201C;outside&#x201D; the sandbox, even though the user already provided their intent &#x2014; permission &#x2014; to do so. If a developer were careless in accessing a file/folder, they may accidentally expand the attackable surface area of their app. This could be especially dangerous if faced with a very aggressive and innovative invader.</p>



<p>Let&#x2019;s walk through the remaining steps involved in accessing &#x2014; writing to &#x2014; a file in a bookmarked folder. Please again review the <code>writeToFileBtnClicked(_ sender: Any)</code> method shown above while pondering these final steps:</p>



<p><strong>STEP 4:</strong> Before writing data to the file, <strong>you must call</strong> the <a href="https://developer.apple.com/documentation/foundation/nsurl/1417051-startaccessingsecurityscopedreso?ref=appcoda.com"><code>startAccessingSecurityScopedResource()</code></a> instance method of the bookmark&#x2019;s <code>NSURL</code>.</p>



<p><strong>STEP 5:</strong> Write text to file at the location specified by the bookmark&#x2019;s URL, where I&#x2019;ve hardcoded and appended a filename to the URL.</p>



<p><strong>STEP 6:</strong> Immediately after you&#x2019;re finished with a bookmark, in this case, writing to a file in the folder it represents, <strong>you must call</strong> the <a href="https://developer.apple.com/documentation/foundation/nsurl/1413736-stopaccessingsecurityscopedresou?ref=appcoda.com"><code>stopAccessingSecurityScopedResource()</code></a> instance method of the bookmark&#x2019;s <code>NSURL</code>. It is very important that you remember to balance every call to <code>startAccessingSecurityScopedResource()</code> with a call to <code>stopAccessingSecurityScopedResource()</code> because:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>If you fail to relinquish your access to file-system resources when you no longer need them, your app leaks kernel resources. If sufficient kernel resources are leaked, your app loses its ability to add file-system locations to its sandbox, such as via Powerbox or security-scoped bookmarks, until relaunched.</p></blockquote>



<p>Now you&#x2019;ve gone through the complete cycle of getting user intent for a file/folder (resource) outside the sandbox, bookmarking that resource, saving the bookmark, closing and reopening the app perhaps multiple times, reading the bookmark, and accessing it without driving the user crazy with too many prompts, from beginning to end. Here&#x2019;s a video showing my app writing a file to a folder, <code>~/Documents</code>, that was bookmarked several sessions back; i.e., writing to a bookmark after the app has been closed and reopened several times:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="980" height="402" src="https://www.appcoda.com/content/images/wordpress/2020/08/writeToBookmarkURL.gif" alt="Deploying Mac Apps Outside App Store: How to Remember User Intent for Folders" class="wp-image-18602"></figure>



<h2 class="wp-block-heading">Conclusion</h2>



<p>After this four-part series covering macOS development, I&#x2019;ve covered a lot of ground, including comparing the differences between distributing macOS apps inside and outside of the Mac App Store, comparing sandboxed and non-sandboxed apps, and considering app security. I&#x2019;ve especially highlighted secure coding techniques in a world increasingly reliant on technology, but also besieged by throngs of malicious hacker-attackers. On a positive note, I&#x2019;ve also shown you how lucrative it can be when you have macOS skills. With the blurring of the lines between iOS and macOS just around the corner with <a href="https://www.apple.com/macos/big-sur-preview/?ref=appcoda.com" class="rank-math-link">macOS Big Sur</a> 11 and iOS 14, it will be increasingly important for you to know about both environments.</p>



<p>This tutorial has shown you how to allow macOS apps to conveniently &#x2014; at least for the user &#x2014; reach outside of their sandboxes without requiring repetitive tasks. Always keep a good user experience in mind when designing your code.</p>



<p>Happy coding!</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Using Packages to create an installer for distributing macOS apps outside of the Mac App Store]]></title><description><![CDATA[<!--kg-card-begin: html-->

<p>macOS developers will most likely be faced with the requirement to build an installer for apps they want to &#x2014; or must &#x2014; distribute outside of the Mac App Store (MAS). There is also substantial economic incentive to explore macOS development targeting sales outside of the MAS. In this tutorial,</p>]]></description><link>https://www.appcoda.com/packages-macos-apps-distribution/</link><guid isPermaLink="false">66612a0f166d3c03cf0114d3</guid><category><![CDATA[macOS programming]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Fri, 10 Jul 2020 01:31:10 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2020/07/4fy0sq4iuow.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->

<img src="https://www.appcoda.com/content/images/wordpress/2020/07/4fy0sq4iuow.jpg" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store"><p>macOS developers will most likely be faced with the requirement to build an installer for apps they want to &#x2014; or must &#x2014; distribute outside of the Mac App Store (MAS). There is also substantial economic incentive to explore macOS development targeting sales outside of the MAS. In this tutorial, I&#x2019;ll be explaining how to use Packages, by far one of the most popular tools for developing macOS app installers. It is used by macOS developers worldwide. I&#x2019;ll provide step-by-step instructions, including many screenshots, walking you through the entire process of building installers. Very importantly, <strong>Packages is freeware</strong>.</p>



<p>A <a href="https://insights.dice.com/2019/12/19/macos-developers-not-warmed-mac-app-store/?ref=appcoda.com">2019 survey</a> found that more macOS app developers exclusively sell outside the MAS than exclusively inside the MAS, a near majority sell both inside <strong>and</strong> outside the MAS, and 58% of macOS developers&#x2019; revenue comes from outside-the-MAS sales.</p>





<h2 class="wp-block-heading">A series of tutorials</h2>



<p>This is the third part in a four-part series of tutorials comparing the differences between distributing macOS apps inside and outside of the MAS, comparing sandboxed and non-sandboxed apps, and considering app security.</p>



<p>In the <a href="https://www.appcoda.com/distribute-macos-apps/">first tutorial in this series</a>, I built a non-sandboxed app, discussed certificates, signed the app, notarized it, briefly talked about building an installer, signed and notarized the installer, and lastly touched on distribution of the app installer.</p>



<p>In <a href="https://www.appcoda.com/mac-app-sandbox/">my second tutorial</a>, I examined the app sandbox and then built an app that, whether sandboxed or not sandboxed, could read and write outside of its container &#x2014; and could be sold and distributed either outside the MAS or through the MAS, both with Apple&#x2019;s blessings.</p>



<p>Finally, in Part IV, I&#x2019;ll guide you step-by-step through the process of &#x201C;remembering&#x201D; a user&#x2019;s intent regarding access to system resources that Apple considers vulnerable to attack by malicious software. Specifically, I&#x2019;ll be discussing a technology called &#x201C;security-scoped bookmarks.&#x201D; Please check <a href="https://www.appcoda.com/author/andrewjaffee/" class="rank-math-link">my column here on AppCoda</a> for Part IV.</p>



<h2 class="wp-block-heading">What is a package?</h2>



<p>Packages can be used to deliver a variety of assets to any number of Macs, but this tutorial will concentrate on building a distributable that installs a macOS app onto a Mac, MacBook Pro, MacBook Air, etc. So, in essence, a package (<code>.pkg</code>) is an app that installs another app &#x2014; plus a few optional dependencies. I&#x2019;ll use the terms &#x201C;package,&#x201D; &#x201C;installer,&#x201D; and &#x201C;distributable&#x201D; interchangeably herein.</p>



<p>In this tutorial, we&#x2019;ll only talk about a &#x201C;flat&#x201D; installer, in other words, our distributable will be one single file with a <code>.pkg</code> extension. You&#x2019;ll see how, despite the fact that my Packages installer project is composed of multiple files, the final <code>.pkg</code> will only be one file. Building &#x201C;bundle&#x201D; installers is beyond the scope of this article.</p>



<p>Finally, did you know that <a href="http://s.sudre.free.fr/Software/Packages/about.html?ref=appcoda.com" class="rank-math-link">&#x201C;Packages&#x2019; distribution is built using Packages. Would you care about a solution that would not do that?&#x201D;</a> I care about and use Packages.</p>



<h2 class="wp-block-heading">Creating an installer</h2>



<p>While Packages is a very intuitive tool, if you&#x2019;ve never used it before and/or never built an installer, it&#x2019;s best to start with a tutorial like mine herein so you know what to expect, get an idea of the general workflow, and learn how to &#x201C;build&#x201D; (generate/compile) an installer, a <code>.pkg</code>. You can download <a href="http://www.appcoda.com/resources/swift5/AppDistributionDemo.zip" class="rank-math-link">my sample Packages project</a> and associated assets, required for getting the most out of this tutorial. It&#x2019;s a <code>.zip</code> file. After downloading it, extract it to a convenient folder on your Mac.</p>



<h3 class="wp-block-heading">Get Packages installed on your Mac</h3>



<p>Download the latest version of Packages from <a href="http://s.sudre.free.fr/Software/files/Packages.dmg?ref=appcoda.com" class="rank-math-link">this link</a> and install it on your Mac. Open the file you just downloaded and follow the onscreen instructions to install Packages. The latest version at the time of writing this tutorial was 1.2.9. Please keep in mind that this excellent tool is <strong>freeware</strong>. I believe Packages is the best app for creating installers for macOS. Full disclosure: I have no personal or financial relationship or interest with Packages&#x2019; author, St&#xE9;phane Sudre. I urge you to use his app and, by doing so, support his efforts.</p>



<h3 class="wp-block-heading">Preparing the environment and metadata for your installer</h3>



<p>Our installer will have a splash screen, &#x201C;readme&#x201D; file, and a license agreement, all contained in three separate files in my downloadable <code>.zip</code>. I&#x2019;ll just show you how to add such files to a Packages installer. I don&#x2019;t need to tell you how to create a text file or rich text file with images (<code>.rtfd</code>), both of which can be created with an editor like macOS&#x2019;s builtin <em>TextEdit</em> app.</p>



<p>The three files I just discussed can be found in the <code>UI_Assets</code> folder with these names:</p>



<ol><li><code>Introduction.rtfd</code></li><li><code>ReadMe.rtf</code></li><li><code>License.rtf</code></li></ol>



<p>When working in production, I urge you to store your Packages projects and user interface (UI) assets in folders that are under source control. If you&#x2019;re using Git, you&#x2019;d <code>git add</code> all your distribution-related files and folders to your repo, <code>commit</code>, and <code>push</code>.</p>



<h3 class="wp-block-heading">Creating a new Packages project</h3>



<p>All the work I&#x2019;ll discuss in the following sections has already been done in my sample Packages project, so you can just follow along or you can recreate the steps I&#x2019;m about to enumerate and elucidate.</p>



<p>We&#x2019;ll start a new installer project by using the Packages <em>Distribution</em> template. Start Packages, go to the <em>File</em> menu, select the <em>New Project&#x2026;</em> option, and the <em>Choose a template for your project:</em> window will pop up:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1300" height="866" src="https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18367" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate.png 1300w, https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate-450x300.png 450w, https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate-1024x682.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate-200x133.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate-768x512.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate-1240x826.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate-860x573.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate-680x453.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate-400x266.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/chooseDistributionTemplate-50x33.png 50w" sizes="(max-width: 1300px) 100vw, 1300px"></figure>



<p>After you select the <em>Distribution</em> template, click <em>Next</em> button. The <em>Choose the name and location for your project:</em> window will be displayed:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1302" height="866" src="https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18368" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject.png 1302w, https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject-451x300.png 451w, https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject-1024x681.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject-200x133.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject-768x511.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject-1240x825.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject-860x572.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject-680x452.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject-400x266.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/createNewPackagesProject-50x33.png 50w" sizes="(max-width: 1302px) 100vw, 1302px"></figure>



<p>Make your <em>Project Name</em> meaningful, like in this example, since the app is named <code>AppNotaryAndDistrib</code>, I&#x2019;ll call it, well, <code>AppNotaryAndDistrib</code>. Click the <em>Choose&#x2026;</em> button to select a <em>Project Directory</em> in which to store the new project file. Save it in the <code>AppDistribution</code> directory in my sample that you downloaded and click the <em>Create</em> button.</p>



<p>Just before your new project file is created, Packages will try to access your contacts, thus causing macOS to go security-gaga and prompt you with this dialog:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="844" height="354" src="https://www.appcoda.com/content/images/wordpress/2020/07/packagesAccessContacts.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18369" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/packagesAccessContacts.png 844w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesAccessContacts-600x252.png 600w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesAccessContacts-200x84.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesAccessContacts-768x322.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesAccessContacts-680x285.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesAccessContacts-400x168.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesAccessContacts-50x21.png 50w" sizes="(max-width: 844px) 100vw, 844px"></figure>



<p>I click the <em>Don&#x2019;t Allow</em> button because I create installers using a variety of Internet domain-based identifiers (e.g., <code>com.domainName.pkg.AppName</code>).</p>



<p>Packages will create a file named <code>AppNotaryAndDistrib.pkgproj</code> where <code>.pkgproj</code> is the extension used for project files. This screen will appear next:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1922" height="766" src="https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18370" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab.png 1922w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-600x239.png 600w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-1024x408.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-200x80.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-768x306.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-1536x612.png 1536w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-1680x670.png 1680w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-1240x494.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-860x343.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-680x271.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-400x159.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/projectSettingsTab-50x20.png 50w" sizes="(max-width: 1922px) 100vw, 1922px"></figure>



<p>Look at the left sidebar for a blue icon with the word <em>Project</em> next to it. Below this, you&#x2019;ll also notice a list of your project&#x2019;s <em>Packages</em>, as a project can be configured to build multiple distributables, like an Xcode project can have multiple targets. Each distributable has a yellow/brown &#x201C;box&#x201D; (package?) icon and, next to it, its name. In today&#x2019;s tutorial, we&#x2019;ll just have one package, which is the name I just assigned the project (<code>AppNotaryAndDistrib</code>).</p>



<p>Highlight the blue <em>Project</em> icon and we&#x2019;ll go through and configure its <em>Settings</em>, <em>Presentation</em>, <em>Requirements &amp; Resources</em>, and <em>Comments</em> tabs respectively. <strong>NOTE: You should be constantly saving changes made to this new Packages project as we go.</strong></p>



<h4 class="wp-block-heading">The project <em>Settings</em> tab</h4>



<p>You can accept most of the default values on this tab, with several exceptions, but let&#x2019;s go through each one. I&#x2019;m referring to the last screenshot I just discussed directly above.</p>



<p>The <em>Name</em> field will contain the same value you just entered as the <em>Project Name</em>. I usually leave this as-is so that the installer we build later will be called <code>[APP_NAME].pkg</code>. Leave the <em>Path</em> field set to <code>build</code> so that the installer we compile will be placed in a folder called <code>build</code> in the <code>AppDistribution</code> project folder I created for this installer. (Note that you can change the build location to whatever you want.) Leave the <em>Reference Folder</em> set to <code>Project Folder</code> so that all project assets and distributables will be referenced relative to the project home folder we chose earlier, and thus be portable and maintainable. Leave the <em>Format</em> set to <code>Flat</code>. This means that your installer will be one (clean) single file with a <code>.pkg</code> extension. Finally, don&#x2019;t change the <em>Exclusions</em> as these are files that rightfully should not be included in your installer. If you find the need to exclude certain files from your installer, e.g., Git files, this would be the place to do so.</p>



<h4 class="wp-block-heading">The project <em>Presentation</em> tab</h4>



<p>On the project&#x2019;s <em>Presentation</em> tab, we&#x2019;ll customize the new installer&#x2019;s user interface and configure some installation options. We&#x2019;ll work our way through the bulleted list of buttons, starting with <em>Introduction</em> going all the way down to <em>Summary</em>:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="2044" height="1176" src="https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18371" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro.png 2044w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-521x300.png 521w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-1024x589.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-200x115.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-768x442.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-1536x884.png 1536w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-1680x967.png 1680w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-1240x713.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-860x495.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-680x391.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-400x230.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsAddIntro-50x29.png 50w" sizes="(max-width: 2044px) 100vw, 2044px"></figure>



<p>Let&#x2019;s start by adding a splash screen. Click on the <em>Introduction</em> button and then click the <em>+</em> button. A placeholder will appear under the <em>Custom Introduction Localizations</em> section, with the default locality being the USA. Activate the dropdown and choose the <code>Introduction.rtfd</code> file in my Packages project file system&#x2019;s <code>UI_Assets</code> folder, as shown in the last screenshot. Notice that Packages already provides terse and basic installer UI screens if you don&#x2019;t want to customize.</p>



<p>Make sure you configure the path to <code>Introduction.rtfd</code> to be <code>Relative to Project</code> so the new <code>.pkgproj</code> is portable, maintainable, and self-contained. Do the same with the &#x201C;readme&#x201D; and license files, like so:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="606" height="294" src="https://www.appcoda.com/content/images/wordpress/2020/07/relativeToProject.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18372" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/relativeToProject.png 606w, https://www.appcoda.com/content/images/wordpress/2020/07/relativeToProject-600x291.png 600w, https://www.appcoda.com/content/images/wordpress/2020/07/relativeToProject-200x97.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/relativeToProject-400x194.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/relativeToProject-50x24.png 50w" sizes="(max-width: 606px) 100vw, 606px"></figure>



<p>Packages immediately previews what my introduction file is going to look like when the installer runs:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="554" src="https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-1024x554.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18373" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-1024x554.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-554x300.png 554w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-200x108.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-768x416.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-1536x831.png 1536w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-1680x909.png 1680w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-1240x671.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-860x465.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-680x368.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-400x216.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview-50x27.png 50w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsIntroPreview.png 1774w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>Go ahead and use the same process to add the custom &#x201C;readme&#x201D; and licensing files I mentioned earlier. I urge you to always provide a license with software you distribute, but keep in mind that I am not a lawyer and this <strong>does not</strong> constitute legal advice. It is up to you to seek out legal counsel and discuss your potential liabilities before you release any software to a client and/or to the public.</p>



<p>The <em>Destination Select</em> button does not apply to us, so we&#x2019;ll skip it and click on <em>Installation Type</em>. This is just a way to give users options as to how and where they&#x2019;ll install the actual <code>.app</code>. We&#x2019;ll keep things super simple and choose to install my sample app using the <code>Standard Install Only</code> protocol. You can give users more options, but I leave it to you to explore those on your own time:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1338" height="1176" src="https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18374" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall.png 1338w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall-341x300.png 341w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall-1024x900.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall-200x176.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall-768x675.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall-1240x1090.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall-860x756.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall-680x598.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall-400x352.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/settingsStandardInstall-50x44.png 50w" sizes="(max-width: 1338px) 100vw, 1338px"></figure>



<p>Notice that I&#x2019;ve highlighted <em>Standard Install on &#x201C;Catalina New&#x201D;</em>. The standard install in this case defaults to the current macOS boot partition on which we&#x2019;ve got Packages running (mine is &#x201C;Catalina New&#x201D;). This means the <code>.pkg</code> will attempt to install the app on the user&#x2019;s current bootable partition.</p>



<p>The <em>Installation</em> button is not relevant to our discussion and the <em>Summary</em> button just shows a screen telling the user that the installation succeeded. I&#x2019;ll show you images of the real installer screens later.</p>



<h4 class="wp-block-heading">The project <em>Requirements &amp; Resources</em> tab</h4>



<p>When you distribute a lot of software, it can make maintenance easier to have all your customers install your app the same way. This tab affords you precise control over where your app can be installed. For example, I have one customer who always ticks the &#x201C;Install on startup disk only&#x201D; checkbox:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1562" height="462" src="https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18375" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk.png 1562w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-600x177.png 600w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-1024x303.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-200x59.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-768x227.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-1536x454.png 1536w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-1240x367.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-860x254.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-680x201.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-400x118.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/installStartupDisk-50x15.png 50w" sizes="(max-width: 1562px) 100vw, 1562px"></figure>



<p>There&#x2019;s no need to go to the <em>Comments</em> tab, so I&#x2019;ll skip it. We&#x2019;re now done with all the <em>Project</em> tabs. Let&#x2019;s move to the <em>Packages</em> tabs.</p>



<h4 class="wp-block-heading">The package&#x2019;s <em>Settings</em> tab</h4>



<p>Remember when we started our new installer project, I pointed out that <em>Packages</em> is the title for the left sidebar of the app? Since a project can be configured to build multiple distributables, each one has a yellow/brown icon next to its name. Remember that we have just one package, which is the name I assigned to the project upon its creation. Click on the package icon named <code>AppNotaryAndDistrib</code>:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1842" height="1142" src="https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18376" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab.png 1842w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-484x300.png 484w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-1024x635.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-200x124.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-768x476.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-1536x952.png 1536w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-1680x1042.png 1680w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-1240x769.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-860x533.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-680x422.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-400x248.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/packagesSettingsTab-50x31.png 50w" sizes="(max-width: 1842px) 100vw, 1842px"></figure>



<p>The <em>Identifier</em> field will be pre-filled with <code>com.mygreatcompany.pkg.AppNotaryAndDistrib</code>, but since this package is for my company, I renamed it. I used <code>us.microit.pkg.AppNotaryAndDistrib</code>. Notice how it starts with the reverse of my company website&#x2019;s domain, http://microit.us. This is also known as your installer&#x2019;s &#x201C;tag,&#x201D; just like your app has a <code>Bundle Identifier</code>.</p>



<p>I left the <em>Version</em> number at <code>1.0</code>, but please use this field to track the version history of your distributables. For <em>On Success</em>, meaning when the installer finishes without a problem, I usually leave it set to <code>Do Nothing</code> but you can also <code>Require Restart</code>, <code>Require Shutdown</code>, or <code>Require Logout</code>. I almost always leave <em>Location</em> as <code>Embedded</code> and you will too most of the time. Trust me &#x2014; or do your own research about the other possible values. Finally, I prefer that <code>Require admin password for installation</code> be ticked so that only the Mac&#x2019;s owner can install software. You can see that there are quite a few options you can set to customize your installer. I urge you to fiddle with these settings and learn about the possibilities.</p>



<h4 class="wp-block-heading">The package&#x2019;s <em>Payload</em> tab</h4>



<p>Without the <em>Payload</em> tab, your Packages project would be useless. The payload is the app to be installed. Here&#x2019;s how I use drag and drop to add my sample app bundle, <code>AppNotaryAndDistrib.app</code>, to our Packages project:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1026" height="508" src="https://www.appcoda.com/content/images/wordpress/2020/07/addAppToInstaller.gif" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18377"></figure>



<p><strong>Remember that the app to be installed must already be signed and notarized before being added to an installer.</strong> I&#x2019;ve included a signed and notarized version of my sample app in [the download for this tutorial](INSERT LINK TO MY PACKAGES PROJECT). I select the <a href="https://www.appcoda.com/distribute-macos-apps/">signed and notarized version of my sample app</a> in <em>Finder</em>, highlight it, and drag it into Packages&#x2019; virtual <em>Finder</em>-like representation of the target Mac&#x2019;s file system. My sample Packages project is arranged so that the target <code>.app</code> sits in the same folder as the project file we&#x2019;re now editing. In most cases you&#x2019;ll drag your app bundle into the project&#x2019;s virtual <code>/Applications</code> folder so your payload, in most cases, an app, will be installed where most other apps are installed.</p>



<p>Notice that as soon as I drag my <code>AppNotaryAndDistrib.app</code> file into the <em>Payload</em> tab, a sheet entitled <em>Choose options for adding these files:</em> pops up asking me if I want configure my project to reference an <code>Absolute Path</code> or <code>Relative Path</code>. If you chose a <em>Reference Style</em> of <code>Absolute Path</code>, then your project will be hardcoded to look for the target app (deliverable) in a specific location on your Mac every time you build your installer. I rather use a <code>Relative Path</code>, that is, relative to the Packages project file. That way, as long as I Xcode-build my target app into the same location specified in my Packages project, I can always build an installer regardless of any hardcoded paths. An example is in order: Which is more supportable, this hardcoded path, <code>/Users/andrewjaffee/Documents/path/to/the/file/target_app_name.app</code>, or this relative path, <code>./target_app_name.app</code>?</p>



<p>The same sheet where you specify the target path has an <em>Ownership</em> checkbox. I suggest you leave this alone now and just set the <em>Reference Style</em> as you&#x2019;ll have the opportunity to scrutinize the target app&#x2019;s permissions in just a moment. Just click the <em>Finish</em> button.</p>



<p>Since I don&#x2019;t want to get into a discussion about macOS (Unix) file permissions, I suggest you leave all the default settings provided by Packages on this <em>Payload</em> tab, like so:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="1048" src="https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18378" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues.png 1200w, https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues-344x300.png 344w, https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues-1024x894.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues-200x175.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues-768x671.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues-860x751.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues-680x594.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues-400x349.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/payloadTabValues-50x44.png 50w" sizes="(max-width: 1200px) 100vw, 1200px"></figure>



<p>This is a nice summary of where and how the <code>.pkg</code> will install the app. The bottom line here is that the permissions should only allow a Mac owner with sufficient rights to allow the installation of a new app in <code>/Applications</code> and <strong>not allow</strong> just any other user to delete or tamper with apps installed in that same folder.</p>



<p>I leave it to you to do your own research and explore the remaining options on this tab.</p>



<h3 class="wp-block-heading">Building the Packages installer</h3>



<p>We&#x2019;re now ready to create a distributable capable of installing my sample app on any compatible Mac. To create the installer/package (<code>.pkg</code>), which is universally understood and executed by macOS, we need to &#x201C;build&#x201D; the installer. Think of this process as akin to compiling an app using Xcode.</p>



<p>Go to the <em>Build</em> menu and select the <em>Build</em> option. You can watch the entire process live in the <em>Build Results</em> window that automatically pops open when you hit that <em>Build</em> option. I encourage you to expand all the line items in the <em>Build Results</em> window and inspect their contents, like so:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1278" height="890" src="https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18379" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow.png 1278w, https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow-431x300.png 431w, https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow-1024x713.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow-200x139.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow-768x535.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow-1240x864.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow-860x599.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow-680x474.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow-400x279.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/buildResultsWindow-50x35.png 50w" sizes="(max-width: 1278px) 100vw, 1278px"></figure>



<p>If any errors occur in your package project configuration, say a missing target app or dependency (e.g., license file), you&#x2019;ll see them in this results dialog. The installer will be placed in the <code>build</code> folder next to my <code>.pkgproj</code> file. As you can see, Packages is a sophisticated software platform that covers all the bases.</p>



<p>Hopefully, the app you&#x2019;re distributing will be well-accepted by your customer base. That probably means you&#x2019;ll be updating your app as time goes by and you&#x2019;ll be reusing your <code>.pkgproj</code> project file. My policy is to save and save often. I regularly save my work as I configure and build a new project and/or update an existing one. Just in case you aren&#x2019;t the regularly-saving type, you&#x2019;ll be prompted to save your new Packages project as soon as you hit that <em>Build</em> menu option.</p>



<h3 class="wp-block-heading">Signing the Packages installer</h3>



<p>In order for you to <strong>properly</strong> distribute your app so your installer runs without generating scary messages from the macOS <code>Gatekeeper</code>, you need to <strong>1)</strong> sign and <strong>2)</strong> notarize the installer. I already covered this process in great detail here on AppCoda <a href="https://www.appcoda.com/distribute-macos-apps/#Creating_an_installer_to_distribute_the_app">several tutorials back</a>. Please read the section in that tutorial entitled &#x201C;Creating an installer to distribute the app,&#x201D; including all its subsections. Then sign and notarize the installer you just built.</p>



<p>You&#x2019;ve just successfully created your first macOS installer!</p>



<h3 class="wp-block-heading">Running the Packages installer</h3>



<p>Double click on the signed and notarized installer and you&#x2019;ll see the following series of screens. <code>AppNotaryAndDistrib.app</code>, version 1.0, will be installed in your <code>/Applications</code> folder. Here are the steps the installer will walk you through:</p>



<figure class="wp-block-gallery columns-3 is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="726" src="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-1024x726.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" data-id="18380" data-full-url="/content/images/wordpress/2020/07/installerStep1.png" data-link="https://www.appcoda.com/?attachment_id=18380" class="wp-image-18380" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-1024x726.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-423x300.png 423w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-200x142.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-768x544.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-1240x879.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-860x610.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-680x482.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-400x284.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1-50x35.png 50w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep1.png 1250w" sizes="(max-width: 1024px) 100vw, 1024px"></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="725" src="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-1024x725.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" data-id="18381" data-full-url="/content/images/wordpress/2020/07/installerStep2.png" data-link="https://www.appcoda.com/?attachment_id=18381" class="wp-image-18381" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-1024x725.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-424x300.png 424w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-200x142.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-768x543.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-1240x878.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-860x609.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-680x481.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-400x283.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2-50x35.png 50w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep2.png 1252w" sizes="(max-width: 1024px) 100vw, 1024px"></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="726" src="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-1024x726.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" data-id="18382" data-full-url="/content/images/wordpress/2020/07/installerStep3.png" data-link="https://www.appcoda.com/?attachment_id=18382" class="wp-image-18382" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-1024x726.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-423x300.png 423w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-200x142.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-768x545.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-1240x879.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-860x610.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-680x482.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-400x284.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3-50x35.png 50w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep3.png 1252w" sizes="(max-width: 1024px) 100vw, 1024px"></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="727" src="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-1024x727.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" data-id="18383" data-full-url="/content/images/wordpress/2020/07/installerStep4.png" data-link="https://www.appcoda.com/?attachment_id=18383" class="wp-image-18383" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-1024x727.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-423x300.png 423w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-200x142.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-768x545.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-1240x880.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-860x611.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-680x483.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-400x284.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4-50x35.png 50w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep4.png 1248w" sizes="(max-width: 1024px) 100vw, 1024px"></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="725" src="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-1024x725.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" data-id="18384" data-full-url="/content/images/wordpress/2020/07/installerStep5.png" data-link="https://www.appcoda.com/?attachment_id=18384" class="wp-image-18384" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-1024x725.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-424x300.png 424w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-200x142.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-768x544.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-1240x878.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-860x609.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-680x482.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-400x283.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5-50x35.png 50w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep5.png 1248w" sizes="(max-width: 1024px) 100vw, 1024px"></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="725" src="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-1024x725.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" data-id="18385" data-full-url="/content/images/wordpress/2020/07/installerStep6.png" data-link="https://www.appcoda.com/?attachment_id=18385" class="wp-image-18385" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-1024x725.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-424x300.png 424w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-200x142.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-768x544.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-1240x878.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-860x609.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-680x482.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-400x283.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6-50x35.png 50w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep6.png 1248w" sizes="(max-width: 1024px) 100vw, 1024px"></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="725" src="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-1024x725.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" data-id="18386" data-full-url="/content/images/wordpress/2020/07/installerStep7.png" data-link="https://www.appcoda.com/?attachment_id=18386" class="wp-image-18386" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-1024x725.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-424x300.png 424w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-200x142.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-768x543.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-1240x878.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-860x609.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-680x481.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-400x283.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7-50x35.png 50w, https://www.appcoda.com/content/images/wordpress/2020/07/installerStep7.png 1252w" sizes="(max-width: 1024px) 100vw, 1024px"></figure></li></ul></figure>



<p>Double-click on the app and in your <code>/Applications</code> folder and, voila, it runs:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="970" height="592" src="https://www.appcoda.com/content/images/wordpress/2020/07/myAppRunning.png" alt="Using Packages to create an installer for distributing macOS apps outside of the Mac App Store" class="wp-image-18387" srcset="https://www.appcoda.com/content/images/wordpress/2020/07/myAppRunning.png 970w, https://www.appcoda.com/content/images/wordpress/2020/07/myAppRunning-492x300.png 492w, https://www.appcoda.com/content/images/wordpress/2020/07/myAppRunning-200x122.png 200w, https://www.appcoda.com/content/images/wordpress/2020/07/myAppRunning-768x469.png 768w, https://www.appcoda.com/content/images/wordpress/2020/07/myAppRunning-860x525.png 860w, https://www.appcoda.com/content/images/wordpress/2020/07/myAppRunning-680x415.png 680w, https://www.appcoda.com/content/images/wordpress/2020/07/myAppRunning-400x244.png 400w, https://www.appcoda.com/content/images/wordpress/2020/07/myAppRunning-50x31.png 50w" sizes="(max-width: 970px) 100vw, 970px"></figure>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Considering that a clear majority of macOS developers distribute and earn revenues on their apps <strong>outside of the Mac App Store</strong>, I would hope that I piqued your interest in Packages. You can&#x2019;t beat the fact that Packages is freeware so, not only did you learn something new about macOS software today, you&#x2019;re opening the doors to beneficial opportunities for yourselves. Enjoy!</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Beyond App Sandbox: Going outside of the macOS app container]]></title><description><![CDATA[<!--kg-card-begin: html-->

<p>Did you know that a macOS app can read and write <strong>outside</strong> of its <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW6">container</a> when <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH1-SW1">sandboxed</a>? Did you know that a <strong>non-sandboxed</strong> macOS app has no container? Were you aware that you can sell and distribute non-sandboxed macOS apps <a href="https://www.appcoda.com/distribute-macos-apps/">without using the Mac App Store</a>? Since the focus of</p>]]></description><link>https://www.appcoda.com/mac-app-sandbox/</link><guid isPermaLink="false">66612a0f166d3c03cf0114ce</guid><category><![CDATA[macOS programming]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Fri, 19 Jun 2020 11:54:02 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2020/06/vsqwu6ckfjk.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->

<img src="https://www.appcoda.com/content/images/wordpress/2020/06/vsqwu6ckfjk.jpg" alt="Beyond App Sandbox: Going outside of the macOS app container"><p>Did you know that a macOS app can read and write <strong>outside</strong> of its <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW6">container</a> when <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH1-SW1">sandboxed</a>? Did you know that a <strong>non-sandboxed</strong> macOS app has no container? Were you aware that you can sell and distribute non-sandboxed macOS apps <a href="https://www.appcoda.com/distribute-macos-apps/">without using the Mac App Store</a>? Since the focus of most Apple development seems concentrated on iOS, many developers probably take the sandbox for granted. Some might not even be fully aware of the sandbox&#x2019;s existence, especially in the case of iOS where <strong>all</strong> apps must be sandboxed. By ignoring the sandbox &#x2014; and possibly <a href="https://www.appcoda.com/macos-programming/" class="rank-math-link">macOS development</a> entirely &#x2014; developers run the risk of neglecting to understand a fundamental piece of Apple&#x2019;s security infrastructure, and fail to take advantage of earning income from developing macOS apps.</p>



<p>Today, we&#x2019;ll take an in-depth look at the sandbox&#x2019;s benefits (and drawbacks) to both users and developers. We&#x2019;ll discover, when merited, how to read/write outside the sandbox, and when and how to develop apps that are not sandboxed at all.</p>



<p><strong>Editor&#x2019;s note:</strong> If you are new to macOS development, you can check out <a href="https://www.appcoda.com/macos-programming/">our macOS tutorial series</a>.</p>





<h2 class="wp-block-heading">A series of tutorials</h2>



<p>This is the second part in a three-part series of tutorials on sandboxing, signing, notarizing, and <a href="https://www.appcoda.com/distribute-macos-apps/" class="rank-math-link">distributing macOS apps</a> outside of the Mac App Store. In this tutorial I&#x2019;ll give you in-depth insight into the sandbox and then build an app that, whether sandboxed or not sandboxed, can read and write outside of its container &#x2014; and can be either sold and distributed outside the Mac App Store (MAS) or through the MAS, both with Apple&#x2019;s blessings. I&#x2019;ll demonstrate how you can build apps safe from malicious code and/or malicious exploitation even if you make exceptions to the sandboxing rules &#x2014; or even if you turn off the sandbox entitlement completely.</p>



<p>You should definitely read my <a href="https://www.appcoda.com/distribute-macos-apps/" class="rank-math-link">first tutorial in this series</a> where I built a non-sandboxed app, discussed certificates, signed the app, notarized it, briefly talked about building an installer, signed and notarized the installer, and lastly covered distribution of the app installer.</p>



<p>Finally, in Part III, I&#x2019;ll guide you step-by-step through the process of using the excellent freeware app <a href="http://s.sudre.free.fr/Software/Packages/about.html?ref=appcoda.com"><em>Packages</em></a> to create an installer for distributing your macOS apps outside the MAS. We&#x2019;ll build an installer that has a splash page, installation instructions, a licensing agreement, and provides installation options for users.</p>



<h2 class="wp-block-heading">What is an app sandbox?</h2>



<p>Apple&#x2019;s <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW1">&#x201C;App Sandbox Design Guide&#x201D;</a> is a bit outdated, stating:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>An app that is not sandboxed has access to all user-accessible system resources&#x2013;including the built-in camera and microphone, network sockets, printing, and most of the file system. If successfully attacked by malicious code, such an app can behave as a hostile agent with wide-ranging potential to inflict harm.</p></blockquote>



<p>I say &#x201C;outdated&#x201D; because, since the advent of Mojave and especially Catalina, I&#x2019;ve seen non-sandboxed macOS apps that, when trying to access system resources, get a system prompt asking if it&#x2019;s OK, for example, to read/write data in the user&#x2019;s <code>~/Documents</code> folder. So we&#x2019;ve defined non-sandboxed apps with my provisos; now let&#x2019;s talk about sandboxed apps.</p>



<p>The app sandbox is meant to keep users safe from apps that contain malicious code or contain vulnerabilities that an attacker can exploit for malicious purposes. The sandbox protects users&#x2019; assets from damage or theft. Apple mandates app sandboxing in iOS app development and strongly recommends it, <a href="https://www.appcoda.com/distribute-macos-apps/">though doesn&#x2019;t require it</a>, for macOS apps. Apple <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxQuickStart/AppSandboxQuickStart.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH2-SW1">describes their notion of sandboxing thusly</a>:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Fine-grained restriction over access to system resources is the heart of how App Sandbox provides protection should an app become compromised by malicious code. Resolving such violations involves adding specific entitlements in Xcode corresponding to the capabilities your app needs.</p></blockquote>



<p>Think of the sandbox as a very constrictive fence surrounding your app. Of course, an app would be useless if this fence was impenetrable. Apps are only useful if they can act on some type of input and produce meaningful output. A sandboxed app comes with its own file system and can solicit input from the user via a user interface. As iOS developers well know, a lot can be done within the sandbox, but notice that, especially soon after installing a new app, iOS intercepts and asks the user for permission for your app to interact with, for example, the microphone, the camera, Bluetooth, location services, etc. macOS apps used to be pretty much free of such constant micromanagement &#x2014; until Mojave and Catalina debuted. Let&#x2019;s briefly talk about a tangible attribute of a sandboxed app to help you fully appreciate the sandboxing concept.</p>



<p>Take a little time to review the file system created by macOS for <strong>each</strong> sandboxed app. After you run the sandboxed version of my sample app for the first time, look in <code>~Library/Containers</code> for a folder named after the app&#x2019;s <code>Bundle Identifier</code>, with the form <code>com.yourDomain.AppNotaryAndDistrib</code>. Compare that folder&#x2019;s contents to those in your own user-level file system at <code>/Users/YOUR_USERNAME</code>, where my own is <code>/Users/andrewjaffee</code>. Notice anything similar? Different? What about the symbolically linked folders in my app&#x2019;s container? Don&#x2019;t just look at those folders, try double-clicking on some and see where you end up.</p>



<p>Remember the quote I posted above from Apple? They want us to start with very little access to system resources and then only request more resources on an <strong>as-needed</strong> basis. Let&#x2019;s use a real project to explore our options for writing apps with varying degrees of access to system resources. Because of scope, time, and space constraints, I&#x2019;ll confine the discussion of resources to the file system, but keep in mind that your vulnerable surface area includes Mac components like network connections, microphones, the camera, Bluetooth, etc.</p>



<h2 class="wp-block-heading">The sample code</h2>



<p>If you want to build a project yourself and follow along, then open up Xcode 11.x and create a new application based on the macOS <code>App</code> template. You can look at my storyboard and code for guidance. Or if you just want to follow along using my existing code, then open my &#x201C;AppNotaryAndDistrib&#x201D; project and walk through it while reading this article. You can download my sample project, built against the OS X 10.15 (Catalina) SDK at <a href="https://github.com/appcoda/MacSandboxDemo?ref=appcoda.com" class="rank-math-link">this link</a>.</p>



<p>If you use my code, remember that you&#x2019;ll have to use Xcode 11.x to configure the settings under <em>TARGETS</em> -&gt; <em>[TARGET_NAME]</em> -&gt; <em>Signing &amp; Capabilities</em> -&gt; <em>Signing</em> with your own <em>Team</em>, <em>Bundle Identifier</em>, <em>Signing Certificate</em>, and possibly <em>Provisioning Profile</em>.</p>



<h3 class="wp-block-heading">Add automatic signing, remove sandboxing, and keep hardening</h3>



<p>Since we&#x2019;re exploring the app sandbox, let&#x2019;s first configure my code <strong>not</strong> to use that security entitlement, i.e., we&#x2019;ll remove the <code>com.apple.security.app-sandbox</code> entitlement via the Xcode UI. Most of you use the <em>Automatically manage signing</em> setting. Go to <em>TARGETS</em> -&gt; <em>[TARGET_NAME]</em> -&gt; <em>Signing &amp; Capabilities</em> and make sure that setting is checked. Delete the <em>App Sandbox</em> capability (entitlement) and leave the default <em>Hardened Runtime</em> capability (build setting), like this, and notice my annotations in red:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="539" src="https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-1024x539.png" alt="Beyond App Sandbox: Going outside of the macOS app container" class="wp-image-18237" srcset="https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-1024x539.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-570x300.png 570w, https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-200x105.png 200w, https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-768x404.png 768w, https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-1240x653.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-860x453.png 860w, https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-680x358.png 680w, https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-400x211.png 400w, https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities-50x26.png 50w, https://www.appcoda.com/content/images/wordpress/2020/06/configureSigningAndCapabilities.png 1360w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>Please read <a href="https://www.appcoda.com/distribute-macos-apps/">Part I of this series</a> if you need a refresher on hardening.</p>



<h3 class="wp-block-heading">Testing the code</h3>



<p>When it comes to non-sandboxed apps, working inside Xcode lets you get away with things you couldn&#x2019;t do outside of it. To make sure my code is actually functional to this tutorial&#x2019;s specifications, you <a href="https://www.appcoda.com/distribute-macos-apps/">should have the requisite certificates and then clean, build, archive, sign (with <code>Developer ID</code>), upload, notarize the app, and drag it into <code>/Applications</code></a> in each section below where we play <strong>outside</strong> the sandbox. Sandboxed apps can be tested within Xcode or just run from the <code>build</code> folder.</p>



<h2 class="wp-block-heading">Getting outside the app sandbox</h2>



<p>There&#x2019;s no doubt that malicious software is out of control. I worked with a government agency that was subject to <strong>10,000</strong> attacks on its IT infrastructure <strong>every day</strong>. It&#x2019;s no surprise that Apple has increasingly emphasized macOS security, most notably with the advent of Mojave and especially Catalina. While sandboxing is not the only security mechanism available to you as a developer, it&#x2019;s a starting point. Let&#x2019;s look at your options for both sandboxed and non-sandboxed apps.</p>



<h3 class="wp-block-heading">Going without sandboxing</h3>



<p>Remember that we removed the sandbox entitlement when we started working with my sample project. You&#x2019;ll have an <code>AppNotaryAndDistrib.entitlements</code> file in the Xcode <code>Project Navigator</code>, but it will be empty. I&#x2019;m going to <code>try</code> to write a new text file to the user&#x2019;s <code>~/Documents</code> folder from an app without an entitlement for sandboxing. Here&#x2019;s my code in <code>ViewController.swift</code>:</p>



<pre class="wp-block-code"><code>...
@IBAction func writeToFileBtnClicked(_ sender: Any) {

    // create the FULLY-QUALIFIED path to the file so
    // we&apos;re SURE we write OUTSIDE any container
    let url = URL(fileURLWithPath: &quot;/Users/andrewjaffee/Documents/test.txt&quot;);

    // prepare text to write to the file
    let fileText = &quot;This is text in the file&quot;;

    // try writing file to the non-sandboxed ~/Documents folder...
    do {
        try fileText.write(to: url, atomically: false, encoding: String.Encoding.utf8)
    }
    catch let error { // ... or find out why write fails
        print(error.localizedDescription)
        // write some code to recover from error
    }

} // end func writeToFileBtnClicked
...</code></pre>



<p>So while this app didn&#x2019;t come from the MAS and isn&#x2019;t sandboxed, it is notarized, and therefore I can write a file to to the <strong>user&#x2019;s <code>~/Documents</code> folder, not a folder in the app sandbox</strong>. I get no special prompts asking for permission to write to the <code>~/Documents</code> folder, though I swear it happens <strong>sometimes</strong>, maybe when an app is downloaded from the web and/or is installed using an installer? Here, it just works:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="596" height="486" src="https://www.appcoda.com/content/images/wordpress/2020/06/writeFileSuccess.gif" alt="Beyond App Sandbox: Going outside of the macOS app container" class="wp-image-18238"></figure>



<h3 class="wp-block-heading">Using Full Disk Access</h3>



<p>You may have installed apps from websites that, when run for the first time, ask you to go, on your Mac, to <em>System Preferences</em> -&gt; <em>Security &amp; Privacy</em> -&gt; <em>Privacy</em>, unlock settings, and grant <em>Full Disk Access</em> to the app that prompted you. These are almost always un-sandboxed apps that need access to as much of your file system as is possible, like malware scanners, disk cleanup utilities, or file backup services. If you didn&#x2019;t grant <em>Full Disk Access</em>, macOS would prompt you for access permission to folders a billion times, thus rendering such software almost useless. As the preference panel for <em>Full Disk Access</em> says, we&#x2019;re talking about permission for:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>&#x2026;data like Mail, Messages, Safari, Home, Time Machine backups, and certain administrative settings for all users of this Mac.</p></blockquote>



<p>You can make it easier on users by wiring up a button like in my sample app entitled &#x201C;Select Full Disk Access.&#x201D; It is wired to this <code>@IBAction</code>:</p>



<pre class="wp-block-code"><code>...
@IBAction func selectFullDiskAccessBtnClicked(_ sender: Any) {

    // we use an Apple-specific URL to open System Preferences
    let url = URL.init(string: &quot;x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles&quot;)
    // we present System Preferences for &quot;Full Disk Access&quot; to the user
    NSWorkspace.shared.open(url!)

}
...</code></pre>



<p>As you see from the image below, my button and code does what it says:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="993" src="https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-1024x993.png" alt="Beyond App Sandbox: Going outside of the macOS app container" class="wp-image-18239" srcset="https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-1024x993.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-309x300.png 309w, https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-200x194.png 200w, https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-768x745.png 768w, https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-1240x1203.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-860x834.png 860w, https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-680x660.png 680w, https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-400x388.png 400w, https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked-50x48.png 50w, https://www.appcoda.com/content/images/wordpress/2020/06/selectFullDiskAccessBtnClicked.png 1394w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p><strong>Do not</strong> conflate or confuse <em>Full Disk Access</em> with sandboxing. If you grant <em>Full Disk Access</em> to a sandboxed app and it reads outside of its container, it will <strong>crash</strong> immediately, killed by the macOS <code>sandboxd</code> daemon. I&#x2019;ll provide an example in the next section.</p>



<h3 class="wp-block-heading">Going with sandboxing</h3>



<p>By now, you understand the simplicity and convenience of using macOS apps that are not sandboxed. But suppose you are <strong>required</strong> to use sandboxing, for example, because you want to submit your app to the Mac App Store (MAS). Add the sandbox capability (and thus entitlement) to your app:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="610" height="540" src="https://www.appcoda.com/content/images/wordpress/2020/06/addSandboxCapability.gif" alt="Beyond App Sandbox: Going outside of the macOS app container" class="wp-image-18240"></figure>



<p>If you add the <code>App Sandbox</code> capability, a corresponding entitlement is added to the project&#x2019;s configuration. Here&#x2019;s the project&#x2019;s <code>.entitlements</code> file after adding sandboxing:</p>



<pre class="wp-block-code"><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;dict&gt;
    &lt;key&gt;com.apple.security.app-sandbox&lt;/key&gt;
    &lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;</code></pre>



<p>What happens if we press my sample app&#x2019;s &#x201C;Write to file&#x201D; button after adding the sandbox entitlement? Give it a try. The app crashes, right? Let&#x2019;s look in <code>Console.app</code> for (redacted) crash logging reported by the system process/daemon <code>sandboxd</code> as an <code>ERROR</code> of category <code>Violation</code>:</p>



<pre class="wp-block-code"><code>Sandbox: AppNotaryAndDist(7030) deny(1) file-write-create /Users/andrewjaffee/Documents/test.txt
Violation:       deny(1) file-write-create /Users/andrewjaffee/Documents/test.txt
Process:         AppNotaryAndDist [7030]
Path:            /path/to/folder/Build/Products/Debug/AppNotaryAndDistrib.app/Contents/MacOS/AppNotaryAndDistrib
Load Address:    0x100000000
Identifier:      com.yourDomain.AppNotaryAndDistrib
Version:         1 (1.0)
Code Type:       x86_64 (Native)
Parent Process:  debugserver [7032]
Responsible:     /path/to/folder/Build/Products/Debug/AppNotaryAndDistrib.app/Contents/MacOS/AppNotaryAndDistrib
User ID:         501
...</code></pre>



<p>At its simplest, when an app is sandboxed, you can <strong>only</strong> write to and read from the folders in the app&#x2019;s <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW6">container</a>. If you want to get down into the really nitty-gritty, you can also read from a list of <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW17">&#x201C;world readable [files], in certain directories, including /bin /sbin &#x2026;,&#x201D;</a> and a few others, but those generally apply to special use cases.</p>



<h4 class="wp-block-heading">Getting user intent for folders outside the sandbox</h4>



<p>What if I determine the user&#x2019;s &#x201C;intent&#x201D; by running my app, clicking my &#x201C;Select folder&#x201D; button, recording the folder the user picked (<code>~/Documents</code>), and then writing a file to that location? What I&#x2019;m doing is saying, &#x201C;Pick a folder (outside the container) where it&#x2019;s OK for the app to read and write.&#x201D; This is one of Apple&#x2019;s methods for limiting the vulnerable surface area of the app to attack by malware. This requires some preparation via Xcode.</p>



<p>Go to <em>TARGETS</em> -&gt; <em>[TARGET_NAME]</em> -&gt; <em>Signing &amp; Capabilities</em> -&gt; <em>App Sandbox</em> -&gt; <em>File Access</em> -&gt; <em>Type</em> -&gt; <em>User Selected File</em> and change <em>Permission &amp; Access</em> from &#x201C;None&#x201D; to &#x201C;Read/Write,&#x201D; as show here:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="912" height="758" src="https://www.appcoda.com/content/images/wordpress/2020/06/sandboxFileAccess.png" alt="Beyond App Sandbox: Going outside of the macOS app container" class="wp-image-18241" srcset="https://www.appcoda.com/content/images/wordpress/2020/06/sandboxFileAccess.png 912w, https://www.appcoda.com/content/images/wordpress/2020/06/sandboxFileAccess-361x300.png 361w, https://www.appcoda.com/content/images/wordpress/2020/06/sandboxFileAccess-200x166.png 200w, https://www.appcoda.com/content/images/wordpress/2020/06/sandboxFileAccess-768x638.png 768w, https://www.appcoda.com/content/images/wordpress/2020/06/sandboxFileAccess-860x715.png 860w, https://www.appcoda.com/content/images/wordpress/2020/06/sandboxFileAccess-680x565.png 680w, https://www.appcoda.com/content/images/wordpress/2020/06/sandboxFileAccess-400x332.png 400w, https://www.appcoda.com/content/images/wordpress/2020/06/sandboxFileAccess-50x42.png 50w" sizes="(max-width: 912px) 100vw, 912px"></figure>



<p>This will add the <code>com.apple.security.files.user-selected.read-write</code> entitlement to your project. Then follow all the usual steps we&#x2019;ve discussed to get a notarized app and run it. Now let&#x2019;s click my <em>Select folder</em> button, choose the <code>~/Documents</code> folder by browsing to it using the <code>NSOpenPanel</code>, highlighting the folder, and pressing the <em>Select</em> button. If we do all this <strong>before</strong> we click my <em>Write file</em> button, then macOS will let us write the <code>test.txt</code> file to the user-selected location, like so:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="756" height="610" src="https://www.appcoda.com/content/images/wordpress/2020/06/showFolderIntent.gif" alt="Beyond App Sandbox: Going outside of the macOS app container" class="wp-image-18242"></figure>



<p>The app <strong>didn&#x2019;t</strong> crash because the user told us that writing to <code>~/Documents</code> was OK. Here&#x2019;s the code behind my app&#x2019;s <em>Select folder</em> button. It&#x2019;s semantically clear and well-commented, so you shouldn&#x2019;t have any problem reading it:</p>



<pre class="wp-block-code"><code>...
/**
 We encourage the user to select a folder, like ~/Documents,
 showing their &quot;intent&quot; to grant our app access to that folder.
 That directory is OUTSIDE of this app&apos;s sandbox. We do this
 in preparation for allowing us to reach out of our container.
*/
@IBAction func selectFolderBtnClicked(_ sender: Any) {

    let folderSelectionDialog = NSOpenPanel() // a modal dialog

    folderSelectionDialog.prompt = &quot;Select&quot;
    folderSelectionDialog.message = &quot;Please select a folder&quot;

    folderSelectionDialog.canChooseFiles = false
    folderSelectionDialog.allowedFileTypes = [&quot;N/A&quot;]
    folderSelectionDialog.allowsOtherFileTypes = false

    folderSelectionDialog.allowsMultipleSelection = false

    folderSelectionDialog.canChooseDirectories = true

    // open the MODAL folder selection panel/dialog
    let dialogButtonPressed = folderSelectionDialog.runModal()

    // if the user pressed the &quot;Select&quot; (affirmative or &quot;OK&quot;)
    // button, then they&apos;ve probably chosen a folder
    if dialogButtonPressed == NSApplication.ModalResponse.OK {

        if folderSelectionDialog.urls.count == 1 {

            if let url = folderSelectionDialog.urls.first {

                // if the user doesn&apos;t select anything, then
                // the URL &quot;file:///&quot; is returned, which we ignore
                if url.absoluteString != &quot;file:///&quot; {

                    // save the user&apos;s selection so that we can
                    // access the folder they specified (in Part II)
                    self.userSelectedFolderURL = url
                    print(&quot;User selected folder: \(url)&quot;)

                } else {
                    print(&quot;User did not select a folder: file:///&quot;)
                }

            } // end if let url = folderSelectionDialog.urls.first {

        } else {

            print(&quot;User did not select a folder&quot;)

        } // end if folderSelectionDialog.urls.count

    } else { // user clicked on &quot;Cancel&quot;

        print(&quot;User cancelled folder selection panel&quot;)

    } // end if dialogButtonPressed == NSApplication.ModalResponse.OK

} // end func selectFolderBtnClicked
...</code></pre>



<p>I find this all very fascinating. Apple is making sure the user carefully considers what folders their already-sandboxed apps will be able to access. This is another tool in the fight to reduce or control the attackable surface area to which apps are exposed.</p>



<h4 class="wp-block-heading">Persistent access outside of the sandbox</h4>



<p>There&#x2019;s a catch to the user showing their intent as in the previous section. The folder selected by the user is only added to your sandbox until the app is closed. If you were to write to that folder after reopening the app, the app would crash. There is a solution, but it&#x2019;s really going beyond the scope of this tutorial. There&#x2019;s not enough space and time to cover everything, so I leave you with <a href="https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011183-CH3-SW16">Apple&#x2019;s very detailed documentation on remembering user intent across app launches</a>. In a nutshell, these docs show you how &#x201C;you can retain access to file-system resources by employing a security mechanism, known as <em>security-scoped bookmarks</em>, that preserves user intent.&#x201D;</p>



<h4 class="wp-block-heading">Specify entitlements to specific Apple-defined folders</h4>



<p>Remember how we obtained access to a folder of the user&#x2019;s choosing outside of the app container in the section above entitled &#x201C;Getting user intent for folders outside the sandbox?&#x201D; Apple provides a simple mechanism for you to declaratively specify permanent access to user-level folders that everyone knows and loves. Go to <em>TARGETS</em> -&gt; <em>[TARGET_NAME]</em> -&gt; <em>Signing &amp; Capabilities</em> -&gt; <em>App Sandbox</em> -&gt; <em>File Access</em> -&gt; <em>Type</em> and change <em>Permission &amp; Access</em> from <code>None</code> to <code>Read/Write</code> or <code>Read Only</code> for <code>Downloads Folder</code>, <code>Pictures Folder</code>, <code>Music Folder</code>, and/or <code>Movies Folder</code>. Of course, these correspond to the paths <code>~/Downloads</code>, <code>~/Pictures</code>, <code>~/Music</code>, and/or <code>~/Movies</code>, respectively. Here&#x2019;s a sample configuration:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="718" height="260" src="https://www.appcoda.com/content/images/wordpress/2020/06/wellKnownFolderAccess.png" alt="Beyond App Sandbox: Going outside of the macOS app container" class="wp-image-18243" srcset="https://www.appcoda.com/content/images/wordpress/2020/06/wellKnownFolderAccess.png 718w, https://www.appcoda.com/content/images/wordpress/2020/06/wellKnownFolderAccess-600x217.png 600w, https://www.appcoda.com/content/images/wordpress/2020/06/wellKnownFolderAccess-200x72.png 200w, https://www.appcoda.com/content/images/wordpress/2020/06/wellKnownFolderAccess-680x246.png 680w, https://www.appcoda.com/content/images/wordpress/2020/06/wellKnownFolderAccess-400x145.png 400w, https://www.appcoda.com/content/images/wordpress/2020/06/wellKnownFolderAccess-50x18.png 50w" sizes="(max-width: 718px) 100vw, 718px"></figure>



<h3 class="wp-block-heading">Using app groups for interprocess communication between your apps</h3>



<p>It&#x2019;s important to have options when creating software solutions to complex problems. Remember that two tutorials back, I wrote about how apps from the same vendor can share a common container, even if some of the apps are sandboxed, some of the apps are not sandboxed, all are sandboxed, or all are not sandboxed. It would be advantageous for you to <a href="https://www.appcoda.com/app-group-macos-ios-communication/">read that tutorial</a>.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>The sandbox can be a powerful tool in the arsenal used to protect users from malicious code. In an ideal world, hopefully in the not-so-distant future, I would hope that the operating system and possibly smart hardware will be improved to reduce the vulnerable surface area of the app runtime environment. Then developers will be able to spend more time on solving problems for users rather than spending hours and hours trying to learn about sandboxing, app groups, security-scoped bookmarks, etc., ad nauseum. Users should be considered, too.</p>



<p>What type of experience is it for users to be constantly bombarded (interrupted) with prompts asking them to make decisions about things they might not even understand, like whether some app needs to access some directory or whether the app can install some &#x201C;helper?&#x201D;</p>



<p>I know I&#x2019;m being hard on OS and hardware designers &#x2014; being a bit of an armchair quarterback &#x2014; but I already put a lot of time into considering how to make my code less vulnerable to malicious exploitation. My hope is for a division of labor, where the OS and hardware folks can strengthen IT security, developers can concentrate on creativity and problem sovling, all so we can all achieve our common goal: useful, creative, and safe apps.</p>



<p>That being said, I hope I&#x2019;ve helped you understand the sandbox, or how not to use the sandbox, and I hope I&#x2019;ve encouraged at least a few developers to give macOS development a chance, especially outside of the MAS, so that they can learn something new and make some extra money.</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store]]></title><description><![CDATA[<!--kg-card-begin: html-->

<p>Since the advent of OS X Mojave and especially Catalina and the requirement for app notarization, some of us old-time macOS developers are concerned that Apple will pull the plug on the apps that we distribute ourselves. Many of you have downloaded and installed macOS software <strong>directly</strong> from websites, i.</p>]]></description><link>https://www.appcoda.com/distribute-macos-apps/</link><guid isPermaLink="false">66612a0f166d3c03cf0114cb</guid><category><![CDATA[macOS programming]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Fri, 29 May 2020 12:48:40 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2020/05/0cdp_vqhd-y.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->

<img src="https://www.appcoda.com/content/images/wordpress/2020/05/0cdp_vqhd-y.jpg" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store"><p>Since the advent of OS X Mojave and especially Catalina and the requirement for app notarization, some of us old-time macOS developers are concerned that Apple will pull the plug on the apps that we distribute ourselves. Many of you have downloaded and installed macOS software <strong>directly</strong> from websites, i.e., <strong>not</strong> from the Mac App Store. Have you ever really considered it? </p>



<p>You can&#x2019;t download an iOS app outside of the App Store. Yes, I know about the Apple Developer Enterprise Program, but it only <a href="https://developer.apple.com/programs/enterprise/?ref=appcoda.com">&#x201C;allows large organizations to develop and deploy proprietary, internal-use apps to their employees.&#x201D;</a> How many of you have obtained tools like <a href="https://www.skype.com/en/get-skype/download-skype-for-desktop/?ref=appcoda.com">Skype</a>, <a href="https://zoom.us/download?ref=appcoda.com">Zoom</a>, <a href="https://atom.io/?ref=appcoda.com">Atom</a>, or <a href="https://www.sourcetreeapp.com/?ref=appcoda.com">Sourcetree</a>? These are all &#x201C;third-party&#x201D; apps not distributed through the Mac App Store. You probably downloaded Xcode from Apple&#x2019;s developer portal (because downloading it from the App Store usually doesn&#x2019;t work). </p>



<p>I would like to share my experiences in developing and distributing macOS apps outside of the Mac App Store and show you how you can do it too. Today, I&#x2019;ll help you understand how to navigate the rather convoluted process of signing and notarizing both an app and its installer. Apple&#x2019;s signing and notarization process can be quite complex and the documentation is not that clear on the subject, especially for installers.</p>



<p><div class="alert gray"><strong>Editor&#x2019;s note</strong>: If you are new to macOS development, you can check out <a href="https://www.appcoda.com/macos-programming/">our macOS tutorial series</a>.</div></p>





<h2 class="wp-block-heading">A series of tutorials</h2>



<p>This is the first part in a three-part series of tutorials on sandboxing, signing, notarizing, and and distributing macOS apps <a href="https://help.apple.com/xcode/mac/current/?ref=appcoda.com#/dev033e997ca"><strong>outside</strong></a> of the Mac App Store. In this tutorial, we&#x2019;ll build a non-sandboxed app, talk about certificates, sign the app, notarize it, briefly talk about building an installer, sign and notarize the installer, and finally cover distribution. In the second tutorial in this series, we&#x2019;ll turn the sandboxing capability and entitlement <strong>on</strong> in my sample app and explore ways that users can still gain access to files and folders <strong>outside</strong> of the app&#x2019;s container. We&#x2019;ll also discuss the pros and cons of sandboxing and try to understand Apple&#x2019;s reasoning behind providing loopholes for sandboxed apps. Finally, in Part III, I&#x2019;ll guide you step-by-step through the process of using the excellent freeware app <a href="http://s.sudre.free.fr/Software/Packages/about.html?ref=appcoda.com"><em>Packages</em></a> to create an installer for distributing your app. We&#x2019;ll build an installer that has a splash page, installation instructions, a licensing agreement, and provides installation options for users.</p>



<h2 class="wp-block-heading">Advantages of staying out of the Mac App Store</h2>



<p>There are several big advantages to distributing macOS apps outside of the Mac App Store. You have much more creative, design, development, distribution, financial, and feature-full options than you would by putting all your work at the risk of sometimes arbitrary rejection by Apple&#x2019;s notoriously fickle and opaque app reviewers.</p>



<p>For example, you don&#x2019;t have to sandbox your apps, giving you access to much of the macOS file system. Another good reason to avoid the App Store: you don&#x2019;t have to follow Apple&#x2019;s sometimes confusing and often draconian Human Interface Guidelines. Probably the best reason: you save lots of money!</p>



<p>Here&#x2019;s a succinct list of the best reasons to distribute your macOS apps outside of the Mac App Store:</p>



<ul><li>you get to advertise, distribute, and sell your app any way and any place you like;</li><li>you <strong>don&#x2019;t</strong> have to pay Apple a 30%/15% fee for selling your apps or for subsequent &#x201C;in app&#x201D; purchases (you can call purchases from within your app anything you&#x2019;d like to call them);</li><li>you don&#x2019;t have to follow Human Interface Guidelines; and,</li><li>you avoid the coin toss of ending up with the disgruntled app reviewer who&#x2019;s just having a bad day.</li></ul>



<h2 class="wp-block-heading">What is Gatekeeper and notarization?</h2>



<p>Before we get started with the tactical discussion, let&#x2019;s clarify the meaning and importance of what Apple calls &#x201C;notarization.&#x201D; There&#x2019;s a <a href="https://support.apple.com/en-us/HT202491?ref=appcoda.com">quote from Apple</a> describing <code>Gatekeeper</code>, positing a situation exactly as I&#x2019;ll discuss herein, where:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>&#x2026; you download and install apps from the internet or directly from a developer, macOS continues to protect your Mac. When you install Mac apps, plug-ins, and installer packages from outside the App Store, macOS checks the Developer ID signature to verify that the software is from an identified developer and that it has not been altered. By default, macOS Catalina also requires software to be notarized, so you can be confident that the software you run on your Mac doesn&#x2019;t contain known malware. Before opening downloaded software for the first time, macOS requests your approval to make sure you aren&#x2019;t misled into running software you didn&#x2019;t expect. &#x2026;</p></blockquote>



<h2 class="wp-block-heading">My sample code</h2>



<p>Let&#x2019;s get started. If you want to build a project yourself and follow along, then open up Xcode (I&#x2019;m using 11.2.1) and create a new application based on the macOS <code>App</code> template. You can look at my storyboard and code for guidance. Or if you just want to follow along using my existing code, then open my &#x201C;AppNotaryAndDistrib&#x201D; project and walk through it while reading this article. You can download my sample project, built against the OS X 10.15 (Catalina) SDK at <a href="https://github.com/appcoda/macOSAppDistDemo?ref=appcoda.com">this link</a>. If you use my code, remember that you&#x2019;ll have to use Xcode 11.x to configure the settings under <em>TARGETS</em> -&gt; <em>[TARGET_NAME]</em> -&gt; <em>Signing &amp; Capabilities</em> -&gt; <em>Signing</em> with your own <em>Team</em>, <em>Bundle Identifier</em>, <em>Signing Certificate</em>, and possibly <em>Provisioning Profile</em>.</p>



<p>I won&#x2019;t be going into Swift coding specifics today as <strong>this</strong> tutorial is concentrated on distributing safe code outside the Mac App Store. We&#x2019;ll concentrate on app configuration herein. If you stay with me, you&#x2019;ll configure, build, sign, and notarize my app. Then you&#x2019;ll configure, build, sign, and notarize an installer for my app. When you run the installer and then run my sample app, you&#x2019;ll see this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="820" height="608" src="https://www.appcoda.com/content/images/wordpress/2020/05/myAppDemo.gif" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18141"></figure>



<p>Let&#x2019;s take just a few minutes to go over the code wired to the button in the center of my main window entitled &#x201C;Select folder.&#x201D; Remember that in Part II of this tutorial, we&#x2019;ll be having a very in-depth discussion about how a user can grant a sandboxed app access to specific folders <strong>outside</strong> of its container. Keep that in mind. For now, let&#x2019;s just say that, from my project&#x2019;s <code>NSViewController</code> subclass, I&#x2019;m using <code>NSOpenPanel</code> to enable the user to select individual folders:</p>



<pre class="wp-block-code"><code>...
@IBAction func selectFolderBtnClicked(_ sender: Any) {

    let folderSelectionDialog = NSOpenPanel()

    folderSelectionDialog.prompt = &quot;Select&quot;
    folderSelectionDialog.message = &quot;Please select a folder&quot;

...

    if dialogButtonPressed == NSApplication.ModalResponse.OK {

...
                    self.userSelectedFolderURL = url
                    print(&quot;User selected folder: \(url)&quot;)
...

    } // end if dialogButtonPressed == NSApplication.ModalResponse.OK

} // end func selectFolderBtnClicked
...</code></pre>



<h2 class="wp-block-heading">App signing and notarization</h2>



<p>Most of you are familiar with building apps and submitting them to the iOS App Store or, in the case of this tutorial, submitting them for review and distribution to the Mac App Store. You also should know why apps must be digitally signed. If not, please take the time to read up on certificates and signing.</p>



<h3 class="wp-block-heading">Preparing for app signing</h3>



<p>I can&#x2019;t cover all the prerequisite components, protocols, and methodologies required to sign and notarize your apps, as this article would turn into a rather lengthy book. Let me point you at some documentation that Apple has provided so that, for example, you can reproduce what I&#x2019;m showing you in this tutorial on your own Macs. Please read <a href="https://developer.apple.com/developer-id/?ref=appcoda.com">&#x201C;Signing Your Apps for Gatekeeper&#x201D;</a>, <a href="https://help.apple.com/xcode/mac/current/?ref=appcoda.com#/dev154b28f09">&#x201C;Create, export, and delete signing certificates&#x201D;</a>, and <a href="https://help.apple.com/xcode/mac/current/?ref=appcoda.com#/dev033e997ca">&#x201C;Distribute outside the Mac App Store (macOS)&#x201D;</a>.</p>



<p>Because I regularly develop, sign, notarize, and distribute macOS apps outside the App Store, I have certificates with the following types of names in my Mac&#x2019;s <em>Keychain</em>, shown below. If you want to distribute outside of the Mac App Store, you&#x2019;ll need to create and export the same type of certificates from your account on Apple&#x2019;s developer portal and install them into your own <em>Keychain</em>, where TEAM_NAME is your own name or your company&#x2019;s &#x201C;Team Name,&#x201D; and TEAM_ID is your/your company&#x2019;s &#x201C;Team ID,&#x201D; from your portal&#x2019;s account. He are the some of the relevant certificates I can see in my <em>Keychain</em>:</p>



<pre class="wp-block-code"><code>Developer ID Installer: TEAM_NAME (TEAM_ID)
Developer ID Application: TEAM_NAME (TEAM_ID)
Apple Worldwide Developer Relations Certification Authority
Developer ID Certification Authority</code></pre>



<p>This is not an exhaustive list of all certificates you need for day-to-day development. These are just the ones most important for signing and notarizing apps and installers. It behooves you to burn the phrase <code>Developer ID</code> into your brain&#x2019;s neural net. From <a href="https://developer.apple.com/support/developer-id/?ref=appcoda.com">Apple&#x2019;s docs</a>:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>For software and applications that are downloaded from places other than the Mac App Store, developers can get a Developer ID certificate and submit their software for notarization by Apple. Digitally signing software with a unique Developer ID and including a notarization ticket from Apple lets <a href="https://support.apple.com/en-us/HT202491?ref=appcoda.com">Gatekeeper</a> verify that the software is not known malware and has not been tampered with.</p></blockquote>



<p>To get you started, here is a screenshot from Apple&#x2019;s developer portal showing how you would create the certificates you need for distribution outside the Mac App Store. It shows the <em>Certificates, Identifiers &amp; Profiles</em> section when you <em>Create a New Certificate</em>:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="182" src="https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-1024x182.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18142" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-1024x182.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-600x106.png 600w, https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-200x35.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-768x136.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-1240x220.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-860x152.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-680x121.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-400x71.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates-50x9.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/createCertificates.png 1354w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>Once you create these certificates, you download and <a href="https://stackoverflow.com/a/38363563/6383003?ref=appcoda.com">install them</a> into your Mac&#x2019;s <em>Keychain</em>.</p>



<h3 class="wp-block-heading">Add automatic signing, remove sandboxing, and keep hardening</h3>



<p>We&#x2019;re going to diverge from from the default macOS app template while simultaneously leaving other settings as-is, re: sandboxing and hardening, respectively. Most of you use the <em>Automatically manage signing</em> setting. Go to <em>TARGETS</em> -&gt; <em>[TARGET_NAME]</em> -&gt; <em>Signing &amp; Capabilities</em> and make sure that setting is checked. Delete the <em>App Sandbox</em> capability (entitlement) and leave the default <em>Hardened Runtime</em> capability (build setting), like this, and notice my annotations in red:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="539" src="https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-1024x539.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18143" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-1024x539.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-570x300.png 570w, https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-200x105.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-768x404.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-1240x653.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-860x453.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-680x358.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-400x211.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities-50x26.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/configureSigningAndCapabilities.png 1360w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>Many apps benefit greatly from having the convenience of accessing files/folders anywhere on your Mac, excluding protected system areas, so my sample app is <strong>not</strong> sandboxed. As for hardening, according to Xcode 11 help:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Hardened Runtime defends your application by preventing modifications to its code and provides fine-grained controls over what can run in your process. Hardening the runtime also prevents access to sensitive resources unless your application pre-declares its intent to use them, which reduces the attack surface by eliminating unnecessary access. These properties help prevent exploitation of your application and <strong>this capability is required for your app to be notarized</strong>. [My emphasis added.]</p></blockquote>



<h3 class="wp-block-heading">Building, signing, and notarizing</h3>



<p>You all are familiar with cleaning and building apps. I&#x2019;m not sure how many of you are involved in the signing of your apps beyond using Xcode&#x2019;s automated certification process when uploading to the App Store. We&#x2019;ll do some manual digital signing herein. We&#x2019;ll walk through the process step-by-step below. Here&#x2019;s an image you know well &#x2014; Xcode&#x2019;s <em>Product</em> menu:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="418" height="690" src="https://www.appcoda.com/content/images/wordpress/2020/05/productMenu.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18144" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/productMenu.png 418w, https://www.appcoda.com/content/images/wordpress/2020/05/productMenu-182x300.png 182w, https://www.appcoda.com/content/images/wordpress/2020/05/productMenu-200x330.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/productMenu-400x660.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/productMenu-50x83.png 50w" sizes="(max-width: 418px) 100vw, 418px"></figure>



<p>Let&#x2019;s <em>Clean Build Folder</em>, <em>Build</em>, and then <em>Archive</em>. The Xcode <em>Organizer</em> window will appear showing the archive you just created:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="255" src="https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-1024x255.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18145" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-1024x255.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-600x149.png 600w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-200x50.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-768x191.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-1536x382.png 1536w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-1680x418.png 1680w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-1240x308.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-860x214.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-680x169.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-400x99.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp-50x12.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/distributeApp.png 1770w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>Click the <em>Distribute App</em> button as highlighted in red in the previous image. This will pop up the <em>Select a method of distribution:</em> dialog, where you&#x2019;ll select <code>Developer ID</code> (with subtitle &#x201C;Distribute directly to customers.&#x201D;), like with the certificates I discussed above. Remember the significance of <strong><code>Developer ID</code></strong>. Click the <em>Next</em> button as shown in red in the next image:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="621" src="https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-1024x621.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18146" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-1024x621.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-495x300.png 495w, https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-200x121.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-768x466.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-1240x752.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-860x521.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-680x412.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-400x242.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID-50x30.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/selectDeveloperID.png 1498w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>The next step is the <em>Select a destination:</em> dialog, where you&#x2019;ll select the <em>Upload</em> option (with subtitle &#x201C;Send to Apple notary service.&#x201D;), where you&#x2019;ll click the <em>Next</em> button to, well, upload your app bundle to Apple for notarization, as shown in the following image:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="622" src="https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-1024x622.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18147" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-1024x622.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-494x300.png 494w, https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-200x121.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-768x467.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-1240x753.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-860x522.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-680x413.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-400x243.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary-50x30.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/uploadToNotary.png 1498w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>Remember the significance of <strong>notarization</strong>. You&#x2019;re sending your app to Apple for a safety inspection. Apple <a href="https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution?language=objc&amp;ref=appcoda.com">&#x201C;scans your software for malicious content [and] checks for code-signing issues.&#x201D;</a></p>



<p>Now you&#x2019;ll see the <em>Re-sign &#x201C;[APP_NAME]&#x201D;:</em> pop-up, where APP_NAME should obviously be the name of the app we want to notarize. Here, it&#x2019;s my sample app, &#x201C;AppNotaryAndDistrib.&#x201D; You&#x2019;ll select <em>Manually manage signing</em> (with caption &#x201C;Select certificates and profiles from your team.&#x201D;), and then click the <em>Next</em> button:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="621" src="https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-1024x621.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18148" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-1024x621.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-495x300.png 495w, https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-200x121.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-768x466.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-1240x752.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-860x521.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-680x412.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-400x242.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning-50x30.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/manuallyManageSigning.png 1498w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>We next get the <em>Select certificate and Developer ID profiles:</em> dialog, where your <em>Team</em> is already known, you set <em>Distribution certificate:</em> to a valid <code>Developer ID</code> certificate that&#x2019;s in your <em>Keychain</em> as I discussed above, and we set the dropdown adjacent to my app&#x2019;s name, specifying provisioning profiles, to &#x201C;None.&#x201D; I can select &#x201C;None&#x201D; because I didn&#x2019;t add any capabilities to this app. (I removed sandboxing and since hardening is required, is there by default, is really a build setting, then it&#x2019;s not considered a capability). Click the <em>Next</em> button:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="621" src="https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-1024x621.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18149" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-1024x621.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-495x300.png 495w, https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-200x121.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-768x466.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-1240x752.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-860x521.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-680x412.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-400x242.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles-50x30.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/selectCertsAndProfiles.png 1498w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>Now we land on a screen entitled <em>Review [APP_NAME].zip content:</em>, where APP_NAME is my sample app, &#x201C;AppNotaryAndDistrib.&#x201D; You may ask yourself, &#x201C;Why the .zip extension?&#x201D; An app bundle is often going to contain a plugin or extension, though in this case it doesn&#x2019;t, and remember that a bundle is a directory structure that often contains components that can be compressed, so zipping adds to performance. Also, the notary service needs to be able to scan one single, definable file. This is your chance to review your app <strong>before</strong> wasting time because you forgot something. You get to see entitlements, plugins, extensions, core app, team, certificate, provisioning profile, etc. When done reviewing, click the <em>Upload</em> button.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="622" src="https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-1024x622.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18150" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-1024x622.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-494x300.png 494w, https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-200x121.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-768x467.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-1240x753.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-860x522.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-680x413.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-400x243.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent-50x30.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/reviewZipContent.png 1498w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>On the next screen, you&#x2019;ll see some messages about handshaking with the Apple server(s), preparing content for upload, and a progress bar showing uploading status. When your app bundle has successfully been sent to Apple&#x2019;s server, you&#x2019;ll see this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="623" src="https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-1024x623.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18151" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-1024x623.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-493x300.png 493w, https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-200x122.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-768x467.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-1240x754.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-860x523.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-680x414.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-400x243.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete-50x30.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/archiveUploadComplete.png 1496w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>Now you wait&#x2026; The length of time it takes for notarization depends on issues like how busy Apple&#x2019;s servers are at the time and how large is your app bundle, but it generally only takes a few minutes. I don&#x2019;t think I&#x2019;ve ever waited longer than 5-7 minutes, and that was back when Apple first started requiring notarization on Catalina, and everyone was scurrying to get their 3rd-party apps inspected:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="621" src="https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-1024x621.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18152" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-1024x621.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-495x300.png 495w, https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-200x121.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-768x466.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-1240x752.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-860x521.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-680x412.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-400x242.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport-50x30.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/notarySuccessExport.png 1498w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>Click the <em>Export&#x2026;</em> button and place the file in a folder of your choosing. I often save it straight to the <code>/Applications</code> folder, because I&#x2019;m literally &#x201C;installing&#x201D; an app that&#x2019;s ready for prime time. If I double-click on my newly-notarized app in <code>/Applications</code>, it runs immediately because it&#x2019;s been <strong>notarized</strong>. Apple&#x2019;s <code>Gatekeeper</code> looks at it and let&#x2019;s it run. But that&#x2019;s not how you should distribute your apps. We need to create an <strong>installer</strong>.</p>



<h2 class="wp-block-heading">Creating an installer to distribute the app</h2>



<p>It is beyond the scope of this tutorial to go into all the details involved in creating an installer. That being said, please come back in about three weeks and look at my posts here on <a href="https://www.appcoda.com/author/andrewjaffee/">AppCoda</a>. I&#x2019;ll provide a very detailed, step-by-step tutorial on using the freeware app <a href="http://s.sudre.free.fr/Software/Packages/about.html?ref=appcoda.com"><em>Packages</em></a> to make the installer used in this tutorial. I believe <em>Packages</em> is <strong>the best</strong> app for creating installation packages on Mac. Full disclosure: I have no personal or financial relationship or interest with <em>Packages&#x2019;</em> author, St&#xE9;phane Sudre. I urge you to use his app and, by doing so, support his efforts.</p>



<p>The best way for you to start learning about building installers using <em>Packages</em> is to download the app, read <a href="http://s.sudre.free.fr/Software/Packages/about.html?ref=appcoda.com">about it</a>, poke around, start a new project, check out related resources, check out its technical specifications, and read some of the tutorials. Remember that in Part III of this series of tutorials I&#x2019;m writing, I&#x2019;ll be showing you exactly how to use <em>Packages</em> to build an installer for the app we&#x2019;re discussing today.</p>



<p>Here&#x2019;s a tip for my upcoming <em>Packages</em> tutorial: Your installer needs a &#x201C;tag,&#x201D; also knows as an &#x201C;identifier,&#x201D; just like your app has a <code>Bundle Identifier</code>. I used <code>us.microit.pkg.AppNotaryAndDistrib</code>. Notice how it starts with the reverse of my company website&#x2019;s domain, again, just like your app bundle ID.</p>



<p>Here&#x2019;s a brief look at how I add my sample app bundle, <code>AppNotaryAndDistrib.app</code>, to the <em>Packages</em> project I created to build a distributable <code>.pkg</code> installer:</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<div style="width: 640px;" class="wp-video"><video class="wp-video-shortcode" id="video-18139-3" width="640" height="360" preload="metadata" controls="controls"><source type="video/mp4" src="https://www.appcoda.com/content/images/wordpress/2020/05/addAppToInstaller.mp4?_=3"><a href="https://www.appcoda.com/content/images/wordpress/2020/05/addAppToInstaller.mp4">/content/images/wordpress/2020/05/addAppToInstaller.mp4</a></video></div>
</div></figure>



<p>After configuring and building my <em>Packages</em> project, I now have a fully functional installer which I named <code>AppNotaryAndDistrib.pkg</code>. <strong>Remember:</strong> I can&#x2019;t distribute this installer because&#x2026; it&#x2019;s <strong>not signed OR notarized</strong> and Apple&#x2019;s <code>Gatekeeper</code> will tell users that it may contain malicious content and that it&#x2019;s from an unknown distributor. So what do we do? We sign the installer and then we notarize it. Believe it or not, this is not a simple process. So let me walk you through it.</p>



<h3 class="wp-block-heading">Installer signing</h3>



<p>You all should know that an installer needs to be <a href="https://developer.apple.com/developer-id/?ref=appcoda.com">signed</a> with a valid certificate, right? It&#x2019;s an application that installs another application on someone&#x2019;s Mac and we don&#x2019;t want anyone tampering with it. Let&#x2019;s sign my installer using one of the <code>Developer ID</code> certificates I discussed earlier using the <a href="https://www.unix.com/man-page/osx/1/productsign/?ref=appcoda.com"><code>productsign</code></a> command in <code>Terminal</code>, and check the output. This command has the form:</p>



<pre class="wp-block-code"><code>productsign --sign &quot;Developer ID Installer: TEAM_NAME (TEAM_ID)&quot; &quot;ORIGINAL_INSTALLER_NAME&quot; &quot;SIGNED_INSTALLER_NAME&quot;</code></pre>



<p>Let&#x2019;s run it with real arguments, like my company name (TEAM_NAME) and file names, except my TEAM_ID, which I&#x2019;ve redacted as &#x201C;ABCABCABCD&#x201D;:</p>



<pre class="wp-block-code"><code>productsign --sign &quot;Developer ID Installer: microIT Infrastructure, LLC (ABCABCABCD)&quot; &quot;AppNotaryAndDistrib.pkg&quot; &quot;AppNotaryAndDistrib_1.0_Installer.pkg&quot;</code></pre>



<p>Here&#x2019;s the output from running the command:</p>



<pre class="wp-block-code"><code>productsign: using timestamp authority for signature
productsign: signing product with identity &quot;Developer ID Installer: microIT Infrastructure, LLC (ABCABCABCD)&quot; from keychain /Users/andrewjaffee/Library/Keychains/login.keychain-db
productsign: adding certificate &quot;Developer ID Certification Authority&quot;
productsign: adding certificate &quot;Apple Root CA&quot;
productsign: Wrote signed product archive to AppNotaryAndDistrib_1.0_Installer.pkg</code></pre>



<p>Notice the last line in the output: You&#x2019;ll find a new file, the signed installer, <code>AppNotaryAndDistrib_1.0_Installer.pkg</code> in the folder where you ran <code>productsign</code>. We can&#x2019;t use this installer yet because it hasn&#x2019;t been <strong>notarized</strong>. Are you ready for some pain, er, ah, fun?</p>



<h3 class="wp-block-heading">Installer notarization</h3>



<p>Because of the previous discussion, you know <strong>why</strong> we need to notarize our installer, but you probably don&#x2019;t know <strong>how</strong>. It&#x2019;s a doozy. Apple certainly didn&#x2019;t make this easy. It&#x2019;s all command line-based and very verbose. <strong>IMPORTANT:</strong> You&#x2019;ll need your Apple ID and your installer&#x2019;s &#x201C;bundle ID,&#x201D; i.e., <code>us.microit.pkg.AppNotaryAndDistrib</code> as we discussed above. If you use two-factor authentication with your Apple ID, you&#x2019;ll need to use <a href="https://support.apple.com/en-us/HT204397?ref=appcoda.com">app-specific passwords</a>. If you don&#x2019;t want to send your Apple ID and password as clear text, you can use <a href="https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow?language=objc&amp;ref=appcoda.com"><em>Keychain</em> placeholders</a>.</p>



<p>Open a <code>Terminal</code> window and follow along as I enter commands and review output. I&#x2019;ll use placeholders for many of the commands&#x2019; arguments so as to redact my private information. We&#x2019;ll start with uploading my installer to Apple for notarization:</p>



<pre class="wp-block-code"><code>xcrun altool --notarize-app --primary-bundle-id &quot;us.microit.pkg.AppNotaryAndDistrib&quot; --username &quot;email@domain.com&quot; --password &quot;PASSWORD&quot; --file AppNotaryAndDistrib_1.0_Installer.pkg</code></pre>



<p><code>Terminal</code> will hang a little while while your installer is uploaded but will come back shortly with the following output:</p>



<pre class="wp-block-code"><code>No errors uploading &apos;AppNotaryAndDistrib_1.0_Installer.pkg&apos;.
RequestUUID = cadc5ae2-768a-4cee-8719-f977c422b1c6</code></pre>



<p>Keep that <code>RequestUUID</code> because you&#x2019;ll use it to check and track the notarization status of your installer. You can wait for an email that will go to your Apple ID, but let&#x2019;s stick with the <code>Terminal</code> workflow. In a few minutes, you&#x2019;ll run this command:</p>



<pre class="wp-block-code"><code>xcrun altool --notarization-history 0 -u &quot;email@domain.com&quot; -p &quot;PASSWORD&quot;</code></pre>



<p>It will return immediately with a log of your notarization results &#x2014; a list of all your submissions and their respective statuses. Look for the line item that has the <code>RequestUUID</code> I asked you to remember. It should be at the top of the list:</p>



<pre class="wp-block-code"><code>Notarization History - page 0

Date                      RequestUUID                          Status  Status Code Status Message
------------------------- ------------------------------------ ------- ----------- ----------------
2020-05-24 19:34:46 +0000 cadc5ae2-768a-4cee-8719-f977c422b1c6 success 0           Package Approved
2020-05-22 05:20:00 +0000 a7b855f8-986c-4df0-a938-24876c588b27 success 0           Package Approved

Next page value: 1590124800000</code></pre>



<p>Yes, the first line item matches my <code>RequestUUID</code>. There it is: &#x201C;Package Approved.&#x201D; The second line item is from my app&#x2019;s notarization that we performed with Xcode earlier in this tutorial.</p>



<p>Your installer is&#x2026; <strong>almost</strong> ready. Note that if Apple hasn&#x2019;t finished notarizing your installer, it will tell you that your request is pending. You can keep submitting the last command to determine if notarization succeeded or failed. What if notarization fails? Can you find out why? Well, yes kinda sorta.</p>



<p>You can get a much more detailed JSON report on notarization status. Let&#x2019;s get started. There are two steps. First, enter this command in <code>Terminal</code> using the installer&#x2019;s <code>RequestUUID</code>:</p>



<pre class="wp-block-code"><code>xcrun altool --notarization-info cadc5ae2-768a-4cee-8719-f977c422b1c6 -u &quot;email@domain.com&quot; -p &quot;PASSWORD&quot;</code></pre>



<p>You&#x2019;ll receive quite a bit of information:</p>



<pre class="wp-block-code"><code>No errors getting notarization info.

          Date: 2020-05-24 19:34:46 +0000
          Hash: 3a5ecc35c373ad872718c8c2c7a4efc21ac5ac3b2739c5e4bef995e910fcf851
    LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123/v4/d2/94/27/d2942733-d44b-5533-fae9-8bbf78d840ba/developer_log.json?accessKey=1590622884_2683968192308681510_zBw4%2BSVyZ%2Fwcy1nlvnkT%2Bo7LVAefv5uDiMG6cz80lAdMrL4mIBCUnhX37utPeGclAZ66U90RdNvhggbBlRF3tuVDJN13uOU3rrSTkLngKRiMDDW3bYcaiSZ2tMqzYBMWykmp%2Fcrs435%2ByIIWmW9E798Ql3Bd1yLBo%2FFDwxeBn8c%3D
   RequestUUID: cadc5ae2-768a-4cee-8719-f977c422b1c6
        Status: success
   Status Code: 0
Status Message: Package Approved</code></pre>



<p>Focus on the <code>Status</code>, <code>Status Code</code>, and <code>Status Message</code> fields for now. As we already know, my installer notarization succeeded (<code>Package Approved</code>). If those three fields contain <strong>anything other</strong> than <code>success</code>, <code>0</code>, and <code>Package Approved</code>, respectively, you can try to find out why your notarization attempt failed by visiting the <code>LogFileURL</code> in your favorite browser. Don&#x2019;t get your hopes up too high. Apple hasn&#x2019;t done the greatest job with its reporting on the results of automated inspections of installers. Still, this is all you can get, and sometimes an obvious mistake it brought to light.</p>



<p>Next up is the second and most important step in getting detailed notarization information. In our case, going to that <code>LogFileURL</code> will be somewhat entertaining, but it&#x2019;s instructive for us to look at the JSON contents that is returned so we can examine its structure. I visited <code>LogFileURL</code> in Safari and here&#x2019;s what I got:</p>



<pre class="wp-block-code"><code>{
  &quot;logFormatVersion&quot;: 1,
  &quot;jobId&quot;: &quot;cadc5ae2-768a-4cee-8719-f977c422b1c6&quot;,
  &quot;status&quot;: &quot;Accepted&quot;,
  &quot;statusSummary&quot;: &quot;Ready for distribution&quot;,
  &quot;statusCode&quot;: 0,
  &quot;archiveFilename&quot;: &quot;AppNotaryAndDistrib_1.0_Installer.pkg&quot;,
  &quot;uploadDate&quot;: &quot;2020-05-24T19:34:46Z&quot;,
  &quot;sha256&quot;: &quot;3a5ecc35c373ad872718c8c2c7a4efc21ac5ac3b2739c5e4bef995e910fcf851&quot;,
  &quot;ticketContents&quot;: [
    {
      &quot;path&quot;: &quot;AppNotaryAndDistrib_1.0_Installer.pkg&quot;,
      &quot;digestAlgorithm&quot;: &quot;SHA-1&quot;,
      &quot;cdhash&quot;: &quot;72e859f50fddcd045091a2bb4ccd8d0bba94633b&quot;
    }
  ],
  &quot;issues&quot;: [
    {
      &quot;severity&quot;: &quot;warning&quot;,
      &quot;code&quot;: null,
      &quot;path&quot;: &quot;AppNotaryAndDistrib_1.0_Installer.pkg&quot;,
      &quot;message&quot;: &quot;This archive is corrupt, and cannot be unpacked for analysis.&quot;,
      &quot;docUrl&quot;: null,
      &quot;architecture&quot;: null
    }
  ]
}</code></pre>



<p>What you&#x2019;re looking at is Apple&#x2019;s attempt to inventory the contents of your submission and scan it for malicious content. I called it &#x201C;entertaining&#x201D; because, while <code>status</code> is &#x201C;Accepted&#x201D; and <code>statusSummary</code> is &#x201C;Ready for distribution,&#x201D; <code>issues</code> is &#x201C;This archive is corrupt, and cannot be unpacked for analysis,&#x201D; but notice it&#x2019;s just a warning. The installer <strong>is not</strong> corrupt because I&#x2019;ve tested it several times and it works great. I believe that Apple feels that it &#x201C;cannot be unpacked for analysis&#x201D; because my installer is <strong>signed</strong> with a valid certificate. I don&#x2019;t want anyone tampering with my installer. DOH! Finally, note the <code>ticketContents</code> field. This has to do with &#x201C;stapling&#x201D; and we&#x2019;ll discuss that in just a moment.</p>



<h3 class="wp-block-heading">Installer stapling</h3>



<p>Now that your installer is notarized, you distribute it to your millions of customers, right? When your customers download and run your installer, Apple knows via an Internet connection through <code>Gatekeeper</code> to allow your installer to proceed. But what if, for a variety of reasons, a customer&#x2019;s Internet connection drops just as they&#x2019;re running your installer? If Apple can&#x2019;t be reached, <code>Gatekeeper</code> won&#x2019;t allow installation. For just such occasions, Apple allows you to &#x201C;staple&#x201D; a &#x201C;ticket&#x201D; to your installer so that it runs, net connection or not:</p>



<pre class="wp-block-code"><code>xcrun stapler staple &quot;AppNotaryAndDistrib_1.0_Installer.pkg&quot;</code></pre>



<p>Here&#x2019;s to what the stapler tells us:</p>



<pre class="wp-block-code"><code>Processing: /Users/andrewjaffee/Documents/AppNotaryAndDistrib_1.0_Installer.pkg
Processing: /Users/andrewjaffee/Documents/AppNotaryAndDistrib_1.0_Installer.pkg
The staple and validate action worked!</code></pre>



<p>We&#x2019;ve got an installer &#x2014; finally. Remember earlier that I test-dragged my sample app into <code>/Applications</code> to kinda install it? I&#x2019;ll delete that now and then run my new installer. Looks what happens:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="727" src="https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-1024x727.png" alt="Beyond the Sandbox: Signing and distributing macOS apps  outside of the Mac App Store" class="wp-image-18153" srcset="https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-1024x727.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-423x300.png 423w, https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-200x142.png 200w, https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-768x545.png 768w, https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-1240x880.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-860x610.png 860w, https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-680x483.png 680w, https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-400x284.png 400w, https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess-50x35.png 50w, https://www.appcoda.com/content/images/wordpress/2020/05/installSuccess.png 1254w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<p>When I look in [<code>/Applications</code>], my <code>AppNotaryAndDistrib.app</code> has been installed. When I double-click on the app icon, it runs and works perfectly. I don&#x2019;t get any warning prompts about &#x201C;malicious&#x201D; software.</p>



<p>You can post an installer like this one on your own website, advertise, and sell it, with the whole process being under your control. This option affords you the most control and the highest profits. You can also sell it through a third party, but that generally eats into your profits. The key takeaway here in that it&#x2019;s <strong>your app</strong> under <strong>your control.</strong></p>



<p>Mission accomplished.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Is notarization all about Apple protecting its customers from potentially malicious software, or is it really an attempt to force <strong>all</strong> OS X app development into the Mac App Store so the giant, trillion-dollar conglomerate can gouge you for enormous fees? My gut feeling is the truth is a mix of the two possibilities, probably 60/40 as Apple already has 100% control over the iOS ecosystem.</p>



<p>There&#x2019;s no question that hacking, identity theft, purposeful and purposeless malicious software-based attacks are a huge and growing problem. Protecting people from such attacks is a noble cause and all developers should keep their users&#x2019; safety in mind when writing code. On the other hand, a free market and the open source phenomena have brought great wealth and knowhow to a world desperately in need of both.</p>



<p>I hope we can find a happy medium. I hope Apple keeps the macOS ecosystem open to third party apps. Be sure to come back for Part II and Part III of this series of tutorials!</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Using App Groups for communication between macOS/iOS apps from the Same Vendor]]></title><description><![CDATA[<!--kg-card-begin: html-->

<p>Apple&#x2019;s &#x201C;app group&#x201D; technology allows a collection of macOS (or iOS) apps from the same development team, developer, vendor, etc., to all communicate with each other, coordinate functionality, share resources, and minimize redundancies. <a href="https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011195-CH4-SW19">Apple says</a> this capability &#x201C;allows the apps within the group to share</p>]]></description><link>https://www.appcoda.com/app-group-macos-ios-communication/</link><guid isPermaLink="false">66612a0f166d3c03cf0114c5</guid><category><![CDATA[macOS programming]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Fri, 10 Apr 2020 00:30:00 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2020/04/jmewnm588-e.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->

<img src="https://www.appcoda.com/content/images/wordpress/2020/04/jmewnm588-e.jpg" alt="Using App Groups for communication between macOS/iOS apps from the Same Vendor"><p>Apple&#x2019;s &#x201C;app group&#x201D; technology allows a collection of macOS (or iOS) apps from the same development team, developer, vendor, etc., to all communicate with each other, coordinate functionality, share resources, and minimize redundancies. <a href="https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011195-CH4-SW19">Apple says</a> this capability &#x201C;allows the apps within the group to share Mach and POSIX semaphores and to use certain other IPC [interprocess communication] mechanisms among the group&#x2019;s members.&#x201D;</p>



<p><strong>A word of caution, though: I&#x2019;ve experienced inconsistent and erratic behavior with macOS app groups, especially on OS X 10.15, Catalina.</strong> As explained below, you may have to experiment with the app group ID format. Nonetheless, this tutorial will help those developers who submit macOS apps through the Mac App Store and those who distribute their apps outside of the Mac App Store by using <em>3rd Party Mac Developer Application</em> and <em>Developer ID</em> certificates &#x2014; including signing and notarization.</p>



<p>Today, I&#x2019;ll walk you through the configuration and encoding of an app group whose members communicate through a shared instance of <a href="https://developer.apple.com/documentation/foundation/userdefaults?ref=appcoda.com"><code>UserDefaults</code></a>, more commonly known as user preferences. One app allows me (and my users) to pick a view background color &#x2014; like a theme color &#x2014; and write it to my shared <code>UserDefaults</code>. The other app can read that same shared preference and update its view&#x2019;s background color to the currently saved value. This process is dynamic. As I change the theme color in one app, the other app can update its view&#x2019;s background color immediately. </p>



<p>We&#x2019;ll build these apps and app group together in this tutorial. You can <a href="https://github.com/appcoda/App-Group-Demo?ref=appcoda.com">download the sample apps here</a>. Here&#x2019;s a video of the two apps coordinating together:</p>



<figure class="wp-block-video aligncenter"><video autoplay loop src="https://www.appcoda.com/content/images/wordpress/2020/04/AppGroupDemo.mp4"></video></figure>



<p>Probably one of the most intriguing aspects of app groups is that their commonly shared container, a mini folder and file system, transcends <a href="http://iosbrain.com/blog/2018/04/22/ios-file-management-with-filemanager-in-protocol-oriented-swift-4/?ref=appcoda.com#sandboxing">sandboxing</a>. To highlight this attribute of app groups, one of my sample apps <strong>is</strong> sandboxed while the other <strong>is not</strong>.</p>



<p>App groups are a great feature, but unfortunately they&#x2019;re not well-documented and therefore generally not well understood. For example, Apple has a section in it&#x2019;s macOS developer documentation called <a href="https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html?ref=appcoda.com#//apple_ref/doc/uid/TP40011195-CH4-SW19">&#x201C;Adding an App to an App Group&#x201D;</a> which strongly implies that all you have to do is add an entitlement to your app&#x2019;s project. In another developer document, Apple states <a href="https://developer.apple.com/documentation/security/keychain_services/keychain_items/sharing_access_to_keychain_items_among_a_collection_of_apps?ref=appcoda.com">&#x201C;You control the groups that your app belongs to by manipulating its entitlements.&#x201D;</a> No mention is made of a very crucial step.</p>



<p>For awhile, adding an app group identifier to an Xcode project&#x2019;s entitlements was sufficient <strong>in macOS</strong> to create and join an app group. Only iOS required that developers have an account with Apple and that they register the app group ID on the Apple Developer portal. That requirement now applies to macOS app groups, too, or does it? We&#x2019;ll talk about this in-depth below.</p>



<p>If you have a number of related apps, especially ones you sell as part of an App Store <a href="https://developer.apple.com/app-store/app-bundles/?ref=appcoda.com">bundle</a>, then app groups might be for you. Keep in mind that apps can be members of more than one app group, too.</p>



<p>Let&#x2019;s walk though all the required steps to create two macOS apps that demonstrate app groups &#x2014; and note that almost all the content herein applies to iOS app groups.</p>



<p><strong>Remember that you&#x2019;ll have to provide your own Apple Developer account&#x2019;s <em>Team ID</em> for creating your own app group ID and for using both of my sample apps.</strong></p>



<h2 class="wp-block-heading">Registering your app group&#x2019;s ID</h2>



<p>The first thing to do when creating an app group is to register an app group ID. Note that each of your apps can belong to, or not belong to, multiple app groups. Have a copy of your Apple Developer account&#x2019;s <em>Team ID</em> ready, like copied into your clipboard. In the screenshots shown below, you&#x2019;ll substitute your own <em>Team ID</em> where I&#x2019;ve redacted my own. Let&#x2019;s get started:</p>



<ol><li>Login to your <a href="https://developer.apple.com/account/?ref=appcoda.com">Apple Developer</a> account;</li><li>Select <em>Certificates, IDs &amp; Profiles</em> from the left sidebar or the center of the screen;</li><li>You&#x2019;ll land on the <em>Certificates</em> screen by default, but select <em>Identifiers</em> from the left sidebar;</li><li>Click the dropdown labelled <em>App IDs</em>, like so:<br></li></ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="531" src="https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-1024x531.png" alt="Using App Groups for communication between macOS/iOS apps from the Same Vendor" class="wp-image-17972" srcset="https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-1024x531.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-579x300.png 579w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-200x104.png 200w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-768x398.png 768w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-1536x796.png 1536w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-1680x871.png 1680w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-1240x643.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-860x446.png 860w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-680x353.png 680w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-400x207.png 400w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs-50x26.png 50w, https://www.appcoda.com/content/images/wordpress/2020/04/Select-the-dropdown-labelled-App-IDs.png 1848w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<ol start="5"><li>Select the <em>App Groups</em> option from the dropdown;</li><li>Now that you&#x2019;re on the <em>Identifiers</em> for <em>App Groups</em> page, click the plus-sign-inside-the-circle button;</li><li>On the <em>Register a New Identifier</em> page that comes up, the <em>App Groups</em> radio button will be auto-selected, like this:</li></ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="161" src="https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected-1024x161.png" alt="Using App Groups for communication between macOS/iOS apps from the Same Vendor" class="wp-image-17973" srcset="https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected-1024x161.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected-600x94.png 600w, https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected-200x31.png 200w, https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected-768x121.png 768w, https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected-860x135.png 860w, https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected-680x107.png 680w, https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected-400x63.png 400w, https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected-50x8.png 50w, https://www.appcoda.com/content/images/wordpress/2020/04/App-Groups-pre-selected.png 1182w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<ol start="8"><li>Click the big, blue <em>Continue</em> button on the upper right-hand side of the same page;</li><li>You&#x2019;ll land on the <em>Register an App Group</em> page where you&#x2019;ll get ready to fill in the <em>Description</em> and <em>Identifier</em> fields;</li><li>Type in a meaningful <em>Description</em> and type/paste your <em>Team ID</em> into the <em>Identifier</em> field;</li><li>Notice that &#x201C;group.&#x201D; is prepended to the <em>Identifier</em>, and that I added some meaningful text, following Apple&#x2019;s suggestion, like this:</li></ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="355" src="https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-1024x355.png" alt="Using App Groups for communication between macOS/iOS apps from the Same Vendor" class="wp-image-17974" srcset="https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-1024x355.png 1024w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-600x208.png 600w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-200x69.png 200w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-768x266.png 768w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-1536x533.png 1536w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-2048x710.png 2048w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-1680x583.png 1680w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-1240x430.png 1240w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-860x298.png 860w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-680x236.png 680w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-400x139.png 400w, https://www.appcoda.com/content/images/wordpress/2020/04/Enter-description-and-identifier-50x17.png 50w" sizes="(max-width: 1024px) 100vw, 1024px"></figure>



<ol start="12"><li>Click the big, blue <em>Continue</em> button;</li><li>You can review your new app group ID, are given the chance to click <em>Back</em> to make changes, but we&#x2019;ll select the <em>Register</em> button; and,</li><li>Now back on the <em>Identifiers</em> for <em>App Groups</em> page, you&#x2019;ll see that you&#x2019;ve created a new app group.</li></ol>



<h3 class="wp-block-heading">What if app group ID registration causes problems?</h3>



<p>Remember that I called app group ID registration a &#x201C;crucial step&#x201D; above? Some people may experience problems with an app group ID of the form <code>group.TEAM_ID.com.domain.MyAppSuite</code>. If you find that you can&#x2019;t sign your app or that your shared container is not created, then <strong>remove</strong> the <code>group.</code> prefix from your app group&#x2019;s ID. So instead of an app group ID of the form <code>group.TEAM_ID.com.domain.MyAppSuite</code>, you&#x2019;ll use one like this: <code>TEAM_ID.com.domain.MyAppSuite</code>.</p>



<h2 class="wp-block-heading">The app group&#x2019;s shared container</h2>



<p>By definition, an app <strong>group</strong> is a collection of two or more apps. Whichever app that is a member of the app group, and runs before any of the other member apps run, creates what&#x2019;s called the group&#x2019;s &#x201C;shared container.&#x201D; It does this once unless someone deletes the container, in which case macOS recreates the container when it is next referenced by one of the group&#x2019;s member apps. That container is a mini folder/file system like those that macOS provides for sandboxed apps. It&#x2019;s a bit like the folder system that macOS builds for each user on a Mac or MacBook. Every shared container is stored in the macOS file system in a folder that has the same name as the app group ID, like <code>group.TEAM_ID.com.domain.MyAppSuite</code>. That folder is always stored in the macOS file system in <code>~/Library/Group Containers/</code>. So the full container path is <code>~/Library/Group Containers/group.TEAM_ID.com.domain.MyAppSuite</code>.</p>



<p>The app group has its own user preferences data store, accessible via a special instance of <code>UserDefaults</code>. These preferences are stored in a <code>.plist</code> file just like they are for all macOS apps. In this tutorial, those preferences are stored in the file at this path:</p>



<pre class="wp-block-code"><code>`~/Library/Group Containers/group.YOUR_TEAM_ID.com.domain.MyAppSuite/Library/Preferences/group.YOUR_TEAM_ID.com.domain.MyAppSuite.plist`</code></pre>



<p>All apps in the app group have read and write access to the shared container, including access to the shared preferences.</p>



<h2 class="wp-block-heading">A Word about my Sample Code</h2>



<p>My code is semantically clear and well commented &#x2014; <strong>but simple</strong>. You shouldn&#x2019;t have any trouble reading it and understanding it. Remember that my code and this accompanying article are pedantic in nature. We&#x2019;re talking about app groups, <strong>not</strong> about using MVC, robust error handling, testing, etc.</p>



<h2 class="wp-block-heading">&#x201C;FirstApp&#x201D; &#x2013; Creating an app that is part of an app group</h2>



<p>Let&#x2019;s walk through building my app group&#x2019;s first app, ingeniously named &#x201C;FirstApp.&#x201D; It reads from and writes to the shared container. My FirstApp writes a color to the shared container&#x2019;s preferences so that my &#x201C;SecondApp&#x201D; can read that preference, and thus we have interprocess communication.</p>



<p>Open up Xcode (I&#x2019;m using 11.2.1) and create a new application based on the macOS <code>App</code> template.</p>



<p>Follow these steps in <em>TARGETS</em> -&gt; <em>Signing &amp; Capabilities</em>:</p>



<ol><li>Tick the <em>Automatically manage signing</em> checkbox and then set the <em>Team</em> and <em>Bundle Identifier</em> appropriately;</li><li>Make sure to that you have the <em>App Sandbox</em> and <em>Hardened Runtime</em> capabilities;</li><li>Click the <em>+</em> button next to <em>Capability</em> and add the <em>App Groups</em> capability by dragging it in from the <em>Library</em>, like this:</li></ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="610" height="350" src="https://www.appcoda.com/content/images/wordpress/2020/04/DragToAddAppGroupCapability.gif" alt="Using App Groups for communication between macOS/iOS apps from the Same Vendor" class="wp-image-17971"></figure>



<ol start="4"><li>Add your app group ID to the <em>App Groups</em> slot (it&#x2019;s actually an array element in the .entitlements file).</li></ol>



<p>Remember that your app group ID should look like this:</p>



<pre class="wp-block-code"><code>group.YOUR_TEAM_ID.com.domain.MyAppSuite</code></pre>



<p>Note that I specifically sandboxed this app to show you that an <strong>app group app can read the shared container, which is outside of this app&#x2019;s sandbox.</strong></p>



<p>Everything you need to see is in the <code>ViewController.swift</code> file. Let&#x2019;s briefly walk through the most important code in FirstApp &#x2014; a few selected snippets.</p>



<p>Let&#x2019;s examine how I write user-selected color values from my app&#x2019;s <code>NSComboBox</code> to the app group&#x2019;s shared preferences. The interprocess communication comes into play when my SecondApp, described below, reads that color preference. Notice that I&#x2019;m getting a special type of reference to <code>UserDefaults</code> by calling its <a href="https://developer.apple.com/documentation/foundation/userdefaults/1409957-init?ref=appcoda.com"><code>init(suiteName:)</code></a> initializer, where the full definition is <code>init?(suiteName suitename: String?)</code>, and note the optional return value. So here&#x2019;s how I access user preferences and set a key/value for my app group by initializing <code>UserDefaults</code> with my app group&#x2019;s ID:</p>



<pre class="wp-block-code"><code>...
/** 3a) Write user preference to shared container. */
func setPreferenceValue(_ value: Any?, forKey key: String, in appGroup: String) {

    // 3b) If we can access preferences to our app group...
    if let groupUserDefaults = UserDefaults(suiteName: appGroup) {

        // 3c) Write the value for the given key
        // to our shared container.
        groupUserDefaults.set(value, forKey: key)
        print(&quot;Wrote to shared user defaults.&quot;)

    }

} // end func setPreferenceValue
...</code></pre>



<p>If you&#x2019;re going to do something with your app group like store common files or maintain a shared cache, you&#x2019;ll need to be able to get a valid macOS file system path to read from, and possibly write to, files/folders in the shared container. To get a URL to the root folder of your shared container, you use the <a href="https://developer.apple.com/documentation/foundation/filemanager/1412643-containerurl?ref=appcoda.com"><code>containerURL(forSecurityApplicationGroupIdentifier:)</code></a> instance method of <code>FileManager</code>, passing it your app group ID. Notice that <a href="https://developer.apple.com/documentation/foundation/filemanager/1416680-iswritablefile?ref=appcoda.com">instead of testing to see if a file exists first before reading from it</a>, I proactively read from it using <code>NSData</code> and then check for a return value:</p>



<pre class="wp-block-code"><code>...
/** 4a) If you&apos;re going to manage and access common resources
 or assets in the shared container, remember that &quot;It&#x2019;s far better to
 attempt an operation (such as loading a file or creating a directory),
 check for errors, and handle those errors gracefully than it is to try
 to figure out ahead of time whether the operation will succeed.&quot;

 - returns: True if plist exists; false if it doesn&apos;t exist
*/
func sharedPreferencesPlistExists() -&gt; Bool {

    var containerExists = false

    let sharedFileManager = FileManager.default

    /* 4b) &quot;In macOS, a URL of the expected form is always returned, even if the app group is invalid, so be sure to test that you can access the underlying directory before attempting to use it.&quot; */
    let sharedContainerFolderURL = sharedFileManager.containerURL(forSecurityApplicationGroupIdentifier: appGroupID)
    // 4c) Now we build a standard path (&quot;Library/Preferences/&quot;)
    // to the preferences data store file (plist). Note
    // the format of the plist&apos;s name.
    let sharedContainerPrefsPlistURL = (sharedContainerFolderURL?.appendingPathComponent(&quot;Library/Preferences/group.YOUR_TEAM_ID.com.domain.MyAppSuite.plist&quot;))!
    // 4d) Try to read data from the preferences
    // plist file.
    let sharedContainerPrefsPlistData = NSData(contentsOf: sharedContainerPrefsPlistURL)
    // 4e) If the file exists...
    if let fileData = sharedContainerPrefsPlistData {

        // 4f) if the plist file has contents (bytes)...
        if fileData.length &gt; 0 {

            // 4g) We know that the plist is valid.
            print(&quot;.plist file size: \(fileData.length)&quot;)
            containerExists = true

        }

    }

    return containerExists

} // func sharedContainerExists()
...</code></pre>



<p>Upon clicking the <em>Check for .plist</em> button in FirstApp, the console shows:</p>



<pre class="wp-block-code"><code>.plist file size: 90
Shared plist created.</code></pre>



<h2 class="wp-block-heading">&#x201C;SecondApp&#x201D; &#x2013; Creating another app so we have an app group</h2>



<p>To restate what I would hope is now the obvious, &#x201C;an app <strong>group</strong> is a collection of two or more apps.&#x201D; SecondApp is, well, the other app that makes up my little app group. SecondApp reads a preference from the shared container. That preference for color is written by FirstApp. SecondApp sets its view controller&#x2019;s <code>NSView</code> background color to the shared container&#x2019;s preference and thus we have interprocess communication.</p>



<p>Open up Xcode (I&#x2019;m using 11.2.1) and create a new application based on the macOS <code>App</code> template.</p>



<p>Follow these steps in <em>TARGETS</em> -&gt; <em>Signing &amp; Capabilities</em>:</p>



<ol><li>Tick the <em>Automatically manage signing</em> checkbox and then set the <em>Team</em> and <em>Bundle Identifier</em> appropriately;</li><li>In this case, make sure to <strong>remove</strong> the <em>App Sandbox</em> capability;</li><li>Make sure the app has the <em>Hardened Runtime</em> capability;</li><li>Click the <em>+</em> button next to <em>Capability</em> and add the <em>App Groups</em> capability by dragging it in from the <em>Library</em>, like this:<br>[DragToAddAppGroupCapability.gif]</li><li>Add your app group ID to the <em>App Groups</em> slot (it&#x2019;s actually an array element in the .entitlements file).</li></ol>



<p>Remember that your app group ID should look like this:</p>



<pre class="wp-block-code"><code>group.YOUR_TEAM_ID.com.domain.MyAppSuite</code></pre>



<p>Everything you need to see is in the <code>ViewController.swift</code> file. Let&#x2019;s briefly walk through the most important code in SecondApp &#x2014; just one selected snippet. Again, I&#x2019;m getting a special type of reference to <code>UserDefaults</code> by calling its <a href="https://developer.apple.com/documentation/foundation/userdefaults/1409957-init?ref=appcoda.com"><code>init(suiteName:)</code></a> initializer with my app group&#x2019;s ID as an argument. This is how I read the user preference for color that was set in FirstApp. I then change my main window&#x2019;s view background color to the preferred color. Here&#x2019;s the code:</p>



<pre class="wp-block-code"><code>...
func setViewBackgroundColor() {

    // 1) Get a reference to the shared user defaults for the
    // app group we created.
    if let groupUserDefaults = UserDefaults(suiteName: appGroupID) {

        // 2) Read the value for the &quot;BackgroundColor&quot; key stored
        // in our app group shared container&apos;s preferences
        // (user defaults).
        if let backgroundColor = (groupUserDefaults.object(forKey: &quot;BackgroundColor&quot;)) as? String {

            // 3) Set the background color of our NSView to
            // the value we read from the our shared container&apos;s
            // preferences.
            self.view.wantsLayer = true

            self.view.needsDisplay = true

            if backgroundColor == &quot;Red&quot; {
                self.view.layer?.backgroundColor = NSColor.red.cgColor
            }
            else if backgroundColor == &quot;Green&quot; {
                self.view.layer?.backgroundColor = NSColor.green.cgColor
            }
            else if backgroundColor == &quot;Blue&quot; {
                self.view.layer?.backgroundColor = NSColor.blue.cgColor
            }
            else {
                self.view.layer?.backgroundColor = NSColor.gray.cgColor
            }

            print(&quot;Read background color, \(backgroundColor), from shared user defaults.&quot;)

        } // end if let backgroundColor =...

    } // end if let groupUserDefaults =...

} // end func setViewBackgroundColor()
...</code></pre>



<p>Note that I specifically didn&#x2019;t sandbox this app to show you that <strong>macOS apps don&#x2019;t necessarily need to be sandboxed (especially those distributed via 3rd party signing) and that non-sandboxed apps can access their app group&#x2019;s shared container.</strong></p>



<h2 class="wp-block-heading">Installing and distributing your macOS apps</h2>



<p>Remember that if you want to install and/or distribute macOS apps like the ones I discussed here, you have two choices. You can go the 3rd party route and sign and notarize your apps outside of the Mac App Store or you can submit your apps for review by staying within the Mac App Store. macOS apps are more flexible in terms of distribution than iOS apps.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>I hope you see the benefits that can be gained by use of app groups, whether it be in iOS or macOS. You can control and update your apps more easily by centralizing shared resources. You can eliminate redundancies. And you can get really advanced by using technologies like shared memory (as long as you remember to keep things thread safe). I could go on and on about the benefits of app groups, but I hope you&#x2019;ll see that, for a relatively small price, you can get a high return on investment.</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[How to Use Git Pull Requests to Improve Code Quality and Developer Participation]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>Today, we&#x2019;ll talk about a feature of several well-known Git tools that I prefer to call a <a href="https://docs.gitlab.com/ee/user/project/merge_requests/?ref=appcoda.com">&#x201C;merge request,&#x201D;</a> but tends often to be referred to as a &#x201C;pull request,&#x201D; for example, on sites like <a href="https://help.github.com/en/articles/about-pull-requests?ref=appcoda.com">GitHub</a> and <a href="https://www.atlassian.com/git/tutorials/making-a-pull-request?ref=appcoda.com">Bitbucket</a>. Using Git-based merge requests tends to</p>]]></description><link>https://www.appcoda.com/git-pull-requests/</link><guid isPermaLink="false">66612a0f166d3c03cf011497</guid><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Tue, 16 Apr 2019 00:01:23 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2019/04/git-pull-request-featured.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->
<img src="https://www.appcoda.com/content/images/wordpress/2019/04/git-pull-request-featured.jpg" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation"><p>Today, we&#x2019;ll talk about a feature of several well-known Git tools that I prefer to call a <a href="https://docs.gitlab.com/ee/user/project/merge_requests/?ref=appcoda.com">&#x201C;merge request,&#x201D;</a> but tends often to be referred to as a &#x201C;pull request,&#x201D; for example, on sites like <a href="https://help.github.com/en/articles/about-pull-requests?ref=appcoda.com">GitHub</a> and <a href="https://www.atlassian.com/git/tutorials/making-a-pull-request?ref=appcoda.com">Bitbucket</a>. Using Git-based merge requests tends to promote cooperation, participation, and collaboration among software team members while they&#x2019;re developing code on mid-sized to large projects. By requiring each software feature or fix to be encapsulated into a formal and easily-identifiable &#x201C;entity,&#x201D; for lack of a better term, pull requests also lend a much-needed sense of structured flow to Git which is, from my perspective, inherently informal in its flow.</p>
<p>As with most aspects of software development, there is no one-size-fits-all model. While merge requests may work wonders on some teams, they may cause confusion with other groups of developers. Pull requests are overkill on very small projects.</p>
<p>Since I work in a full range of software development contexts, from large projects with hundreds of members to small projects with as few as 2 to 5 members, and since full-fledged adoption of this nascent technology is still gaining ground, in this article, just as in my client base, I&#x2019;ll refer to merge requests throughout this article as &#x201C;pull requests,&#x201D; &#x201C;PRs,&#x201D; &#x201C;merge requests&#x201D;, and &#x201C;MRs.&#x201D; This will help readers become adaptive, capable of understanding software terminology regardless of where they&#x2019;re working.</p>
<p>I myself only saw the start of widespread use of merge requests by my clients several years ago. Technically, <a href="https://github.blog/2012-05-02-how-we-use-pull-requests-to-build-github/?ref=appcoda.com">they&#x2019;re not that new</a>, but practically, pull requests are still in the process of being adopted across the Git community.</p>
<div class="alert gray">Editor&#x2019;s note: If you have no idea how to work with Git in Xcode, you can <a href="https://www.appcoda.com/git-xcode/">check out this tutorial</a>.</div>
<h2>An Overview of Git Pull Request (or Merge Request)</h2>
<p>Merge requests provide us with two direct benefits:</p>
<ol>
<li>Encapsulating software features or fixes into readily-identifiable containers</li>
<li>Promoting cooperation, participation, and collaboration by team members while they&#x2019;re developing software code features and fixes.</li>
</ol>
<p>When I say &#x201C;container,&#x201D; I mean that Git value-added service providers like GitHub, Bitbucket, and GitLab have all clearly defined what constitutes a merge request. They&#x2019;ve also enabled development teams to apply unique and meaningful identifiers to each merge request. Communication tools that encourage team member collaboration are built into each merge request.</p>
<p>Generally, a merge request is made up of a distinct code branch that was created (split off) from whatever branch your team has identified as your project&#x2019;s penultimate (best, correct, and truthful) publicly-releasable branch &#x2014; many will immediately think <code>master</code>. The MR contains a pointer to the penultimate (<code>master</code>) branch. The service provider makes it easy for you to identify and compare code in your feature/fix branch with the penultimate branch. You are provided the ability to merge your feature/fix branch into the penultimate branch.</p>
<p>In fact, you should be provided with sophisticated merge tools. The merge request provides a central meeting place where team members can communicate specifically about the feature/fix branch. Commits/pushes to the feature/fix branch are tracked by the merge request.</p>
<p>Team members can easily see differences between the penultimate branch and the feature/fix branch. All team member discussions about the feature/fix branch are recorded in the merge request &#x2014; and discussions associated with each distinct commit/push are shown as distinctly related to each distinct commit/push. Discussions and corresponding commits/pushes are stored in chronological order.</p>
<p>Hooks are provided so that each commit/push can be run through a continuous integration (CI) and continuous delivery and deployment (CD) pipeline. Hooks are provided so that other third party tools can be integrated with merge requests, for example, content management systems that allow meta data about source code, like design documentation, expected timelines, and feature/fix priorities, to be associated with the MR&#x2019;s feature/fix Git branch.</p>
<div class="alert gray"><strong>Note:</strong> Because of the open source and intrinsically distributed nature of the Git source control management system, there is no one &#x201C;official&#x201D; definition and implementation of the Git merge request/pull request. If you are a key decision maker, I would urge you to shop around before committing to one particular vendor/service provider. For example, one of my clients had a continuous integration and continuous delivery/deployment integration that was a total nightmare.</div>
<h2>Warnings and Recommended Reading</h2>
<p>Let me break this to you gently: <strong>If don&#x2019;t understand Git, get to know it before plunging into this article.</strong> Maybe that&#x2019;s too harsh. Generally, I expect you to have at least intermediate working knowlege and proficiency in the use of source control management systems, especially Git. Specifically, this tutorial is meant for at least intermediate to expert Git users.</p>
<p>Here&#x2019;s some recommended reading no matter how much of a Git expert you are. And remember, there really isn&#x2019;t anyone who understands <strong>everything</strong> about Git, myself included.</p>
<ul>
<li><a href="https://www.atlassian.com/git/tutorials/learn-git-with-bitbucket-cloud?ref=appcoda.com">&#x201C;Learn Git with Bitbucket Cloud&#x201D;</a>, Bitbucket</li>
<li><a href="https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow?ref=appcoda.com">&#x201C;Gitflow Workflow&#x201D;</a>, Bitbucket</li>
<li><a href="https://nvie.com/posts/a-successful-git-branching-model/?ref=appcoda.com">&#x201C;A successful Git branching model&#x201D;</a>, Vincent Driessen</li>
<li><a href="https://docs.gitlab.com/ee/workflow/gitlab_flow.html?ref=appcoda.com">&#x201C;Introduction to GitLab Flow&#x201D;</a>, GitLab</li>
</ul>
<h2>Best Practices</h2>
<p>If you&#x2019;re going to start using merge requests to add structure to your Git flow, start with a gentle introductory trial period. Pick just a few seasoned developers, especially ones whom understand Git and your Git tool of choice (i.e., GitHub). Assign them one feature or fix and see how it goes.</p>
<p>Whether starting with merge requests or whether they&#x2019;re already part of your Git flow, try to keep the requirements for features and fixes simple and focused on as few issues as possible. For example, assignments shouldn&#x2019;t be overly broad, like &#x201C;add a settings screen with functionality.&#x201D; Stay focused, like &#x201C;allow the user to control location services in the preferences bundle; just use a <code>UISwitch</code> to enable or disable location tracking.&#x201D;</p>
<p>With the Git flow model <em>I personally</em> prefer to use in mid- to large-sized projects, <em>every</em> feature and fix gets implemented in a separate branch. That branch is tracked, discussed, considered for merging, refined, and finally merged or rejected using a merge request.</p>
<h2>Conventions</h2>
<p>To keep things simple in this article, I myself will play all lead and development roles in the sample merge request that we&#x2019;ll walk through. There will be the &#x201C;team lead (me)&#x201D; and the &#x201C;developer (me).&#x201D;</p>
<p>You know that in most real-life projects, there would be multiple development team members and multiple Git/GitHub user accounts. But here, when playing certain roles or changing roles, I&#x2019;ll write things like &#x201C;the developer (me) is about to commit and push a new feature branch to the remote&#x201D; or &#x201C;the team lead (me) is going to review and comment on the most recent merge request.&#x201D;</p>
<h2>A Simple Environment</h2>
<p>In most mid- to large-sized projects, I encourage a Git branching model as described by Atlassian in <a href="https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow?ref=appcoda.com">this article</a>. But my article here is didactic in nature. I don&#x2019;t want to try to introduce and explain merge requests using a complex and heavy branching configuration to which I just linked. This has one <em>master</em>, one <em>develop</em>, and many <em>feature</em>, <em>defect</em>, and (tagged) <em>release</em> branches. I want you to easily read and understand my presentation. So we&#x2019;ll discuss a project model in which there is only one <em>master</em> branch and possibly several <em>feature</em>/<em>fix</em> branches, and we&#x2019;ll call this &#x201C;master-feature.&#x201D;</p>
<p>In this article, we&#x2019;ll use the Git configuration provided by GitHub if you <a href="http://iosbrain.com/blog/2017/02/11/creating-a-new-gitgithub-repository-for-your-xcode-project-a-detailed-tutorial/?ref=appcoda.com">create a new default repository for your project</a> &#x2014; in other words, a Git configuration that starts with one default branch, <em>master</em>.</p>
<p>You should easily be able to extrapolate from my simplified master-feature configuration to the more complex master-develop-feature/defect-release-tag configuration. In fact, in some small projects, a master-feature/defect configuration may be all you need.</p>
<p>There&#x2019;s an old idiom called <a href="https://lawsofux.com/occams-razor?ref=appcoda.com">&#x201C;Occam&#x2019;s Razor&#x201D;</a> which specifies that the simplest solution is generally the best one.</p>
<h2>A Real-world Merge Request Scenario</h2>
<p>To show you how a merge request works, I&#x2019;ll create an Xcode project written using Swift with some basic functionality. Then I&#x2019;ll implement a new feature in that project by creating a merge request and taking it through an entire, typical MR lifecycle.</p>
<p>As team lead (me), I&#x2019;ll specify a new project requirement and assign implementation of that requirement to developer me. Then developer (me) will create a new Git feature branch, write some new code in that branch, and create a pull request using that branch. Developer (me) will assign my new merge request to team lead (me) for review. Team leader and developer will collaborate on refining the new feature branch code using the pull request as a means for communication. When team lead (me) is satisfied with refinements made to the feature branch by developer (me), team lead will the <em>merge</em> the refined feature branch into <code>master</code> for release. Both developer and team lead will <em>work together</em> &#x2014; collaborate &#x2014; using GitHub&#x2019;s pull request support.</p>
<p>Generally, a &#x201C;successful&#x201D; pull request means that all participants have bought into the story behind a feature, have tuned or at least discussed the code for implementing that feature, and that the feature&#x2019;s code is merged into the <code>master</code> branch for public release.</p>
<p>But &#x201C;success&#x201D; can also mean that the collective wisdom of the pull request&#x2019;s participants have discovered that a proposed new feature or a fix doesn&#x2019;t make sense for this project; that the feature/fix has fundamental design flaws; that the feature/fix would only make sense in the next version of the app, etc.</p>
<p>The <a href="https://github.com/iosbrain/MergeRequestDemo?ref=appcoda.com">sample project</a> can be found on GitHub. The history of the pull request we&#x2019;ll walk through in this article is available for you to inspect, like <a href="https://github.com/iosbrain/MergeRequestDemo/pulls?q=is%3Apr+is%3Aclosed&amp;ref=appcoda.com">here</a> and <a href="https://github.com/iosbrain/MergeRequestDemo/pull/1?ref=appcoda.com">here</a>.</p>
<h3>Following along</h3>
<p>You&#x2019;ll learn more if you recreate all the steps I demonstrate in this article. You can do it yourself like I did, playing the roles of developer and team lead, or you can have even more fun and use an existing team configuration on GitHub &#x2014; or set up a new team &#x2014; so you and your compatriots can fill the various, different team roles that usually work together on a merge request (developers, team leads, reviewers, Scrum Masters, etc.).</p>
<p>However you do it, I encourage you to at minimum interact with the GitHub interface as I do here (like <a href="https://help.github.com/en/articles/creating-a-pull-request?ref=appcoda.com">this</a>).</p>
<h3>Creating the New Repo</h3>
<p>You should all be familiar with how to create a Git/GitHub repo for an Xcode project. If you&#x2019;re not, please read <a href="http://iosbrain.com/blog/2017/02/11/creating-a-new-gitgithub-repository-for-your-xcode-project-a-detailed-tutorial/?ref=appcoda.com">this article</a>.</p>
<p>By following these steps, you should have one default branch named <code>master</code> from which you release code to your customers.</p>
<h3>First Draft Code</h3>
<p>I created a simple Swift project with basic logic and user interface to provide the basis for a weather temperature checking app. It allows you to click on a button and get the current temperature in Fahrenheit (&#xB0;F). I&#x2019;ve mocked up a service for getting the current temperature. There are plenty of <a href="https://openweathermap.org/api?ref=appcoda.com">free APIs</a> out there if you want to take this further and provide real weather info.</p>
<p>Here&#x2019;s the first draft core code for the app:</p>
<pre class="swift">import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var temperatureLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        // Initialize - we haven&apos;t checked temperature yet.
        temperatureLabel.text = &quot;-- F&quot;
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // Get temperature, format for presentation, and
    // display on screen.
    @IBAction func checkTempButtonTapped(_ sender: Any) {
        
        let temperature = getTemperature()
        temperatureLabel.text = String(temperature) + &quot; F&quot;
        
    }
    
    // Mock up a weather/temperature service.
    func getTemperature() -&gt; Int {
        return Int(arc4random_uniform(99))
    }
    
}
</pre>
<p>In the course of managing this project, and since this was the first code written, team lead (me) reviewed this first version of our current temperature viewing app and found that the user interface/user experience (UI/UX) was not very exciting:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15066" src="https://www.appcoda.com/content/images/wordpress/2019/04/no_animate.gif" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="324" height="414"></p>
<p>So, as team lead, I asked one of my developers to improve the UX with some animation.</p>
<h3>Create a new feature branch</h3>
<p>Developer&#x2019;s first step is to create what&#x2019;s called a &#x201C;feature branch.&#x201D; By putting new code into a separate branch, a development boutique can continue forward with app fixes, improvements, experimentation, etc., all without risking the code in the <code>master</code> branch. <code>master</code> is reserved <em>only</em> for app code in a state ready to be released to the public.</p>
<p>Many of you Git users know this already: To add a new feature or fix a defect, you pull from the latest <code>develop</code> or <code>master</code> remote to the corresponding local, and you branch off that latest local, giving the branch an appropriate name. Then you start working on the defect or feature <em>independent</em> of both the local and remote <code>develop</code> or <code>master</code> branches.</p>
<pre class="swift">$ git branch -a
* master
  remotes/origin/master

$ git branch -r
  origin/master

$ git checkout -b FEATURE-add-animation
Switched to a new branch &apos;FEATURE-add-animation&apos;

$ git push -u origin FEATURE-add-animation

Total 0 (delta 0), reused 0 (delta 0)
remote: 
remote: Create a pull request for &apos;FEATURE-add-animation&apos; on GitHub by visiting:
remote:      https://github.com/iosbrain/MergeRequestDemo/pull/new/FEATURE-add-animation
remote: 
To https://github.com/iosbrain/MergeRequestDemo.git
 * [new branch]      FEATURE-add-animation -&gt; FEATURE-add-animation
Branch &apos;FEATURE-add-animation&apos; set up to track remote branch &apos;FEATURE-add-animation&apos; from &apos;origin&apos;.
</pre>
<p>Notice that I immediately pushed my new local feature branch to <code>origin</code> to create a remote version that tracks the new local. Some may argue that this is an unnecessary step because I haven&#x2019;t made any changes to my new feature branch yet. Those people may be right but, for the purposes of this article, I wanted you to be able to see that <em>other</em> team members can now see my new feature branch on the GitHub web interface.</p>
<h3>Local and Remote Versions of the Feature Branch</h3>
<p>Here&#x2019;s GitHub showing the new feature branch:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15050" src="https://www.appcoda.com/content/images/wordpress/2019/04/branch_added.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="728" height="290" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/branch_added.png 728w, https://www.appcoda.com/content/images/wordpress/2019/04/branch_added-200x80.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/branch_added-600x239.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/branch_added-680x271.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/branch_added-400x159.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/branch_added-50x20.png 50w" sizes="(max-width: 728px) 100vw, 728px"></p>
<p>Here&#x2019;s GitHub showing all project branches:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15073" src="https://www.appcoda.com/content/images/wordpress/2019/04/view_branches.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1190" height="490" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/view_branches.png 1190w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-200x82.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-600x247.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-768x316.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-1024x422.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-860x354.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-680x280.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-400x165.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-50x21.png 50w" sizes="(max-width: 1190px) 100vw, 1190px"></p>
<p>Here&#x2019;s GitHub showing detail on all project branches:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15068" src="https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1994" height="912" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches.png 1994w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-200x91.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-600x274.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-768x351.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-1024x468.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-1680x768.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-1240x567.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-860x393.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-680x311.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-400x183.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/overview_branches-50x23.png 50w" sizes="(max-width: 1994px) 100vw, 1994px"></p>
<p>Here are some Git commands for inspecting all project branches from Terminal, seeing the current branch, and for switching branches:</p>
<pre class="swift">$ git branch -a

* FEATURE-add-animation
  master
  remotes/origin/FEATURE-add-animation
  remotes/origin/master
  
$ git branch -l

* FEATURE-add-animation
  master
  
$ git checkout master

Switched to branch &apos;master&apos;
Your branch is up to date with &apos;origin/master&apos;.

$ git checkout FEATURE-add-animation

Switched to branch &apos;FEATURE-add-animation&apos;
Your branch is up to date with &apos;origin/FEATURE-add-animation&apos;.

$ git branch -r
  origin/FEATURE-add-animation
  origin/master
</pre>
<h3>First Version of the New Feature</h3>
<p>Developer (me) was assigned the task of spicing up the temperature app&#x2019;s UX. I added the following code to branch <code>FEATURE-add-animation</code>:</p>
<pre class="swift">...
    // Get temperature, format for presentation, and
    // display on screen.
    @IBAction func checkTempButtonTapped(_ sender: Any) {
        
        temperatureLabel.alpha = 0.0
        
        UIView.animate(withDuration: 2.0) {
            
            self.temperatureLabel.alpha = 1.0
            let temperature = self.getTemperature()
            self.temperatureLabel.text = String(temperature) + &quot; F&quot;
        }
        
    }
...
</pre>
<p>As the developer, I then committed my new code and pushed it to the remote <code>FEATURE-add-animation</code> branch:</p>
<pre class="swift">$ git add MergeRequestDemo/ViewController.swift

$ git commit -m &quot;Added some animation.&quot;

[FEATURE-add-animation 2b34e33] Added some animation.
 1 file changed, 8 insertions(+), 2 deletions(-)

$ git push origin FEATURE-add-animation

Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 462 bytes | 462.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/iosbrain/MergeRequestDemo.git
   40333c3..2b34e33  FEATURE-add-animation -&gt; FEATURE-add-animation
</pre>
<p>Now everyone on the project can see this change. If other team members go to the project&#x2019;s main page on GitHub, they can view and click on the branches tab:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15073" src="https://www.appcoda.com/content/images/wordpress/2019/04/view_branches.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1190" height="490" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/view_branches.png 1190w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-200x82.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-600x247.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-768x316.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-1024x422.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-860x354.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-680x280.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-400x165.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/view_branches-50x21.png 50w" sizes="(max-width: 1190px) 100vw, 1190px"></p>
<p>Then they&#x2019;ll see that developer me has updated <code>FEATURE-add-animation</code>:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15056" src="https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1992" height="924" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated.png 1992w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-200x93.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-600x278.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-768x356.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-1024x475.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-1680x779.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-1240x575.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-860x399.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-680x315.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-400x186.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/feature_branch_updated-50x23.png 50w" sizes="(max-width: 1992px) 100vw, 1992px"></p>
<p>Notice that GitHub emphasizes that developer me has added new code to <code>FEATURE-add-animation</code> by visually presenting the fact that my feature branch is now &#x201C;1 commit ahead of master.&#x201D;</p>
<h3>What to do with the New Feature Branch</h3>
<p>What does a team without a well-defined Git flow do now? Does developer email team lead to ask that the feature branch be approved and merged into <code>master</code>? What if there were a way to highlight the fact that branch <code>FEATURE-add-animation</code> should be discussed by some or all team members to elicit technical input and creative input, and ensure that the new branch&#x2019;s code adheres to standards, etc?</p>
<p>There is a way to get other team members involved. We can do so by having developer me create a merge request, or as it&#x2019;s called on GitHub, a <em>pull request</em>.</p>
<h2>Creating a Merge Request</h2>
<p>Developer should announce to team lead (and others on the team) that I&#x2019;ve taken a stab at encoding animation in the app. I do this by using a feature supported by value-added Git software suites like GitHub, GitLab, or Bitbucket. From <a href="https://help.github.com/en/articles/creating-a-pull-request?ref=appcoda.com">GitHub</a>:</p>
<blockquote><p>Create a pull request to propose and collaborate on changes to a repository. These changes are proposed in a branch, which ensures that the master branch only contains finished and approved work.</p>
<p>Pull requests can only be opened if there are differences between your branch and the upstream branch. You can specify which branch you&#x2019;d like to merge your changes into when you create your pull request. &#x2026;</p></blockquote>
<p>Let&#x2019;s go to GitHub and <a href="https://help.github.com/en/articles/creating-a-pull-request?ref=appcoda.com">walk through this process</a>. I like to start this process on the branch overview page, similar to the flow we used above, like so:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15065" src="https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1982" height="504" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button.png 1982w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-200x51.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-600x153.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-768x195.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-1024x260.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-1680x427.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-1240x315.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-860x219.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-680x173.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-400x102.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/new_pull_request_button-50x13.png 50w" sizes="(max-width: 1982px) 100vw, 1982px"></p>
<p>Developer (me) will push the &#x201C;New pull request&#x201D; button next to my feature branch, as shown in the previous image. Since this is a new <strong>merge</strong> request, the first thing I do is select my feature branch and set it to be eventually merged into <code>master</code>. After all, <code>master</code> is the branch from which my hypothetical team does its releases. Note that GitHub&#x2019;s documentation <a href="https://help.github.com/en/articles/creating-a-pull-request?ref=appcoda.com">states</a>:</p>
<blockquote><p>When thinking about branches, remember that the <em>base branch</em> is <strong>where</strong> changes should be applied, the <em>head branch</em> contains <strong>what</strong> you would like to be applied.</p></blockquote>
<p>Besides making sure I&#x2019;ve selected the proper base and head branches, I can edit the title for my MR (which has been pre-filled with my last commit message) and add detailed commentary if I want:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15067" src="https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1990" height="1074" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr.png 1990w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-200x108.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-556x300.png 556w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-768x414.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-1024x553.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-1680x907.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-1240x669.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-860x464.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-680x367.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-400x216.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/open_an_mr-50x27.png 50w" sizes="(max-width: 1990px) 100vw, 1990px"></p>
<p>Before hitting the green &#x201C;Create pull request&#x201D; button, I should consider to whom I&#x2019;ll assign this MR for review and possible further coding. Remember that the purpose of MRs is <a href="https://help.github.com/en/articles/creating-a-pull-request?ref=appcoda.com">&#x201C;to propose and collaborate on changes to a repository&#x201D;</a>. Developer is going to select team lead as an &#x201C;Assignee.&#x201D; In terms of overall Git flow, generally I like to let the team lead decide if she/he wants to just merge the new feature as is, send it back to developer for changes, ask developer questions, ask others for input, reassign the branch to another developer, etc.:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15049" src="https://www.appcoda.com/content/images/wordpress/2019/04/assignees.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="616" height="318" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/assignees.png 616w, https://www.appcoda.com/content/images/wordpress/2019/04/assignees-200x103.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/assignees-581x300.png 581w, https://www.appcoda.com/content/images/wordpress/2019/04/assignees-400x206.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/assignees-50x26.png 50w" sizes="(max-width: 616px) 100vw, 616px"></p>
<p>Now press that &#x201C;Create pull request&#x201D; button.</p>
<h3>Responding to Merge Requests</h3>
<p>Because merge/pull requests have become so important to the workflow of numerous software development shops, they are made obvious on sites like GitHub. In fact, the &#x201C;Pull requests&#x201D; tab is the first tab you&#x2019;ll probably notice when navigating to the GitHub site:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15069" src="https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="2014" height="460" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs.png 2014w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-200x46.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-600x137.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-768x175.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-1024x234.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-1680x384.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-1240x283.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-860x196.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-680x155.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-400x91.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/prominent_mrs-50x11.png 50w" sizes="(max-width: 2014px) 100vw, 2014px"></p>
<p>If you&#x2019;re working on an active GitHub project, you&#x2019;re going to be loading the remote repo&#x2019;s home page frequently, and it&#x2019;s hard to miss the &#x201C;Pull requests&#x201D; tab. Clicking on it regularly is a best practice for you to see what&#x2019;s going on with your project:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15051" src="https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1230" height="612" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests.png 1230w, https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests-200x100.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests-600x300.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests-768x382.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests-1024x510.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests-860x428.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests-680x338.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests-400x199.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/checking_pull_requests-50x25.png 50w" sizes="(max-width: 1230px) 100vw, 1230px"></p>
<p>Clicking &#x201C;Pull requests&#x201D; shows me an overview of the project&#x2019;s MRs:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15048" src="https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="2022" height="806" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs.png 2022w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-200x80.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-600x239.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-768x306.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-1024x408.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-1680x670.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-1240x494.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-860x343.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-680x271.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-400x159.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-50x20.png 50w" sizes="(max-width: 2022px) 100vw, 2022px"></p>
<h3>What a list of Merge Requests can Tell me about a Project</h3>
<p>Clicking the &#x201C;Pull Requests&#x201D; button or tab on GitHub will show me all MRs assigned to me for review, ones where I should respond to comments, ones I&#x2019;ve been asked to review, or ones I&#x2019;ve been assigned to work on, among other things. Also shown are essentials like how many MRs of mine are currently in process (&#x201C;Open&#x201D;) and a history of previous MRs (&#x201C;Closed&#x201D;). The closed MRs can often be very helpful in remembering features or defects I&#x2019;ve worked on &#x2014; and I can even look at code I wrote, and diffs, and discussions elaborating on the decision-making required to encode, for example, a story, and that discussion comprises a project history, so that I can remember why I coded a certain feature a certain way for whatever reasons. That history may also show me a something like a key algorithm that is demonstrative of the app&#x2019;s core purpose.</p>
<p>But history goes even deeper. I can look at MRs assigned to specific developers and determine essential metrics on say, which developers turned stories into features the fastest, which developers delivered the highest quality code, which developers required the most help and took longest to encode features/fixes, and even which developers (or other team leads) provided the highest quality feedback over time.</p>
<h3>Inspecting your Pull Requests</h3>
<p>Here, I have only one pull request, but in a typical project, I&#x2019;d have several or more likely, many assigned to me:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15048" src="https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="2022" height="806" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs.png 2022w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-200x80.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-600x239.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-768x306.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-1024x408.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-1680x670.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-1240x494.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-860x343.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-680x271.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-400x159.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/assigned_mrs-50x20.png 50w" sizes="(max-width: 2022px) 100vw, 2022px"></p>
<p>I click on my MR to look at its details. When working with clients whose Git flows are based around the merge request model, I check my MRs frequently &#x2014; whether on GitHub, GitLab, Bitbucket, etc. On GitHub and most all other similar sites, I can get a lot of good information by examining an MR assigned to me:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15063" src="https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1990" height="998" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail.png 1990w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-200x100.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-598x300.png 598w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-768x385.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-1024x514.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-1680x843.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-1240x622.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-860x431.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-680x341.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-400x201.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_detail-50x25.png 50w" sizes="(max-width: 1990px) 100vw, 1990px"></p>
<p>Immediately obvious to me is the fact that this MR is still &#x201C;Open,&#x201D; I can see a chronological history of events, and perhaps most importantly, the phrase &#x201C;<strong>iosbrain</strong> wants to merge 1 commit into <code>master</code> from <code>FEATURE-add-animation</code>&#x201D; tells me a lot. Who out there knows how important this statement should be to any team lead or developer? This is all great info. Let me mention a few things that you can look into on your own. Scroll down the page a bit and you&#x2019;ll see two things I&#x2019;d like to highlight:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15062" src="https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1552" height="526" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci.png 1552w, https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci-200x68.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci-600x203.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci-768x260.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci-1024x347.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci-1240x420.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci-860x291.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci-680x230.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci-400x136.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/more_commits_and_ci-50x17.png 50w" sizes="(max-width: 1552px) 100vw, 1552px"></p>
<p>Notice the phrase highlighted at the top of the image. That&#x2019;s telling developer me that I can commit and push from <code>FEATURE-add-animation</code> as many times as necessary to address the concerns of team lead me or other team members.</p>
<p>Now focus on the section of the image that I highlighted mentioning the fact that &#x201C;Continuous integration has not been set up.&#x201D; You&#x2019;ll probably end up in a Git flow where CI/CD <em>has</em> been set up. Then you&#x2019;ll find out whether your current branch&#x2019;s commits/pushes made it through <a href="https://github.com/marketplace/category/continuous-integration?ref=appcoda.com">continuous integration</a>. CI/CD is beyond the scope of this simple tutorial, but you should <a href="https://docs.gitlab.com/ee/ci/README.html?ref=appcoda.com">read up on the topic</a>.</p>
<p>Notice that the MR itself has a menu bar. Let&#x2019;s click the &#x201C;Files changed (1)&#x201D; tab:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15064" src="https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1324" height="554" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff.png 1324w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff-200x84.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff-600x251.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff-768x321.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff-1024x428.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff-1240x519.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff-860x360.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff-680x285.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff-400x167.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/mr_diff-50x21.png 50w" sizes="(max-width: 1324px) 100vw, 1324px"></p>
<p>As you might expect, that tab shows, well, changes to source files, but most importantly, <em>diffs</em> so team members can see the changes made by developer me to the code:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15074" src="https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="2360" height="1108" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs.png 2360w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-200x94.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-600x282.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-768x361.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-1024x481.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-1680x789.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-1240x582.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-860x404.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-680x319.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-400x188.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/view_mr_diffs-50x23.png 50w" sizes="(max-width: 2360px) 100vw, 2360px"></p>
<p>It doesn&#x2019;t get much better than this. By using MRs, we are dividing and conquering a project into manageable, logical, and focused pieces of code, source control flow, standard operating procedures, etc.</p>
<h2>Discussing the Code</h2>
<p>In this section, we&#x2019;ll cover one of the most important features afforded by merge requests: The ability to tap into your development team&#x2019;s collective knowledge and get feedback about code written in the branch attached to the pull request.</p>
<p>I&#x2019;m team leader right now. Because I&#x2019;m working by myself in my own GitHub account, I can only ask for feedback from myself, but that doesn&#x2019;t help you readers out there.</p>
<p>If this were a particularly complex merge request and I needed or wanted advice from other people on my team, I want to click on the &#x201C;Conversation&#x201D; tab and concentrate on the column on the right-hand side of the screen:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15055" src="https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1556" height="696" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab.png 1556w, https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab-200x89.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab-600x268.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab-768x344.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab-1024x458.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab-1240x555.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab-860x385.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab-680x304.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab-400x179.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/conversation_tab-50x22.png 50w" sizes="(max-width: 1556px) 100vw, 1556px"></p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15070" src="https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="2012" height="742" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees.png 2012w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-200x74.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-600x221.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-768x283.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-1024x378.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-1680x620.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-1240x457.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-860x317.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-680x251.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-400x148.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/reviewers_assignees-50x18.png 50w" sizes="(max-width: 2012px) 100vw, 2012px"></p>
<p>If this were a more sophisticated feature, I could ask for input from other developers, other team leads &#x2014; perhaps someone on the creative side, like a UI/UX specialist, or someone in management. I can assign <a href="https://help.github.com/en/articles/requesting-a-pull-request-review?ref=appcoda.com">reviewers</a> and kick off a formal <a href="https://help.github.com/en/articles/about-pull-request-reviews?ref=appcoda.com">review process</a>. I strongly encourage you to look over the links I just provided on formal reviews. This is a means of getting feedback on the merge request from almost anyone with access to your GitHub project.</p>
<p>Say I click the &#x201C;Files changed (1)&#x201D; tab again. By looking at the code and asking the developer me for a demo, I call tell that the animation is OK, but not good enough for me:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15072" src="https://www.appcoda.com/content/images/wordpress/2019/04/some_animate.gif" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="324" height="414"></p>
<p>One way to communicate to the developer, or other team members, is to leave comments in the pull request&#x2019;s code (and diff) view. I can place comments on each line of code. Team lead is going to tell developer what I think about her/his solution and ask for changes:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15054" src="https://www.appcoda.com/content/images/wordpress/2019/04/comment_for_feedback.gif" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="604" height="584"></p>
<p>You see how I was able to start a comment on a specific line number in the relevant code branch. I can get the attention of the developer by using the <code>@</code> key-character, which autocompletes to a matching team member &#x2014; in this case, developer me. Here&#x2019;s the full comment that team leader me left for developer me:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15058" src="https://www.appcoda.com/content/images/wordpress/2019/04/final_comment.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1136" height="1150" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/final_comment.png 1136w, https://www.appcoda.com/content/images/wordpress/2019/04/final_comment-200x202.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/final_comment-296x300.png 296w, https://www.appcoda.com/content/images/wordpress/2019/04/final_comment-768x777.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/final_comment-1012x1024.png 1012w, https://www.appcoda.com/content/images/wordpress/2019/04/final_comment-860x871.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/final_comment-680x688.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/final_comment-400x405.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/final_comment-50x51.png 50w" sizes="(max-width: 1136px) 100vw, 1136px"></p>
<p>If all your team&#x2019;s GitHub notification settings are configured properly, developer, team lead, and other team members should receive a copy of this comment. The developer and team leader and others can go back and forth trading comments as long as they need to, and an audit trail of the conversation is archived in the MR.</p>
<p>As general practice, after team lead is satisfied with a round of commentary, I would now set the &#x201C;Assignees&#x201D; back to developer (me), thus sending the code back to the programmer to make the changes I elucidated in my comments.</p>
<div class="alert gray"><strong>Note:</strong> I&#x2019;m going to remove myself as the &#x201C;Assignee&#x201D; now just so I can show you how team lead me would assign this merge request back to developer me.</div>
<p>Select developer (me) as one of the &#x201C;Assignees&#x201D; (on a team, I would probably use auto-search and autocomplete):</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15071" src="https://www.appcoda.com/content/images/wordpress/2019/04/set_dev_me_assigned.gif" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="366" height="286"></p>
<p>I emphasize again that the developer can make code changes and commit/push them to <code>FEATURE-add-animation</code>, the team lead can review those changes and ask for more changes, this cyclical process can go on as long as necessary, and that at some point the developer will write code that meets the team lead&#x2019;s expectations.</p>
<p>Remember that we can go to the GitHub &#x201C;Files changed (N)&#x201D; tab and compare the <code>master</code> and <code>FEATURE-add-animation</code> branches to see how working code has progressed so far.</p>
<p>The purpose of a merge request is to get more people involved in the development process so that they can spot potential problems (like logic errors or usability problems), ensure that project protocols are followed (like code style/formatting rules), and once in awhile, someone comes up with feedback that is truly inspirational and changes the whole course of the project.</p>
<h2>Final Version of the Feature</h2>
<p>Developer saw team lead&#x2019;s comments on the merge request. First, I make sure I&#x2019;m in my <code>FEATURE-add-animation</code> branch and then I make the following code changes as per team lead&#x2019;s comments:</p>
<pre class="swift">...
    @IBAction func checkTempButtonTapped(_ sender: Any) {
        
        let temperature = getTemperature()
        let temperatureString = String(temperature) + &quot; F&quot;
        
        UIView.animate(withDuration: 2.0, animations: {
            self.temperatureLabel.alpha = 0.0
        }) { (success) in
            UIView.animate(withDuration: 2.0, animations: {
                self.temperatureLabel.alpha = 1.0
                self.temperatureLabel.text = temperatureString
            })
        }
        
    } // end func checkTempButtonTapped
...
</pre>
<p>Developer inspects my final animation:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15057" src="https://www.appcoda.com/content/images/wordpress/2019/04/final_animate.gif" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="326" height="414"></p>
<p>I then commit and push my latest changes into <code>FEATURE-add-animation</code>.</p>
<pre class="swift">$ git status
On branch FEATURE-add-animation
Your branch is up to date with &apos;origin/FEATURE-add-animation&apos;.

Changes not staged for commit:
  (use &quot;git add ...&quot; to update what will be committed)
  (use &quot;git checkout -- ...&quot; to discard changes in working directory)

    modified:   MergeRequestDemo/ViewController.swift

no changes added to commit (use &quot;git add&quot; and/or &quot;git commit -a&quot;)
</pre>
<p>After testing my code (and functional and UI testing), it&#x2019;s ready to commit and push my code.</p>
<pre class="swift">$ git add MergeRequestDemo/ViewController.swift

$ git commit -m &quot;Added fade out animation of old temperature. Then animated in new temperature.&quot;

[FEATURE-add-animation dca55ac] Added fade out animation of old temperature. Then animated in new temperature.
 1 file changed, 10 insertions(+), 7 deletions(-)
 
$ git push origin FEATURE-add-animation
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 545 bytes | 545.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/iosbrain/MergeRequestDemo.git
   2b34e33..dca55ac  FEATURE-add-animation -&gt; FEATURE-add-animation
</pre>
<p>Since developer has pushed the latest code, I&#x2019;ll want to set the &#x201C;Assignees&#x201D; on the pull request back to the team lead. We&#x2019;ll see later that my latest changes are tracked by GitHub via the pull request.</p>
<h2>Reviewing code one final time</h2>
<p>Team lead will want to review the last commit by developer, check for any comments I added to the MR as developer and team lead may want to ask developer some questions (like &#x201C;How did testing go?&#x201D; &#x2014; or&#x2026; &#x201C;Where&#x2019;s your unit test!&#x201D; &#x1F61C;). Team lead could also grab the <code>FEATURE-add-animation</code> branch and run the code myself. So could other team members.</p>
<p>Team lead (me) will be notified by GitHub that developer (me) made changes to the code in the MR. I will use the MR interface to review the new code. I already showed you how to navigate the MR screens on GitHub. We&#x2019;ll look at a couple of those screens now.</p>
<p>The main &#x201C;Conversations&#x201D; screen for this particular merge request will show a chronological summary of what&#x2019;s happened during the lifetime of the request:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15060" src="https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1398" height="1164" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview.png 1398w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview-200x167.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview-360x300.png 360w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview-768x639.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview-1024x853.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview-1240x1032.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview-860x716.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview-680x566.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview-400x333.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview-50x42.png 50w" sizes="(max-width: 1398px) 100vw, 1398px"></p>
<p>Most of this is self-explanatory. Notice I&#x2019;ve highlighted some sections of the screen and numbered them &#x201C;#1&#x201D; and &#x201C;#2.&#x201D; Team lead clicks on #1 first. We&#x2019;ll discuss that in a moment, but let me just plant this seed in your head: When I scroll further down the page, I see this:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15059" src="https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1406" height="938" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge.png 1406w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge-200x133.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge-450x300.png 450w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge-768x512.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge-1024x683.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge-1240x827.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge-860x574.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge-680x454.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge-400x267.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/final_mr_overview_w_merge-50x33.png 50w" sizes="(max-width: 1406px) 100vw, 1406px"></p>
<p>See that big green &#x201C;Merge pull request&#x201D; button that I&#x2019;ve marked &#x201C;#3?&#x201D; We&#x2019;ll also discuss that soon.</p>
<h3>Discussion of #1, #2, and #3 &#x2014; then merging</h3>
<p>When I get notified about a pull request like this, team lead clicks on the link in #1 first. The screen section marked #1 represents the last action performed on this MR (developer me&#x2019;s last commit/push). GitHub takes me to the following screen:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15052" src="https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="2250" height="1284" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1.png 2250w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-200x114.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-526x300.png 526w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-768x438.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-1024x584.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-1680x959.png 1680w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-1240x708.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-860x491.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-680x388.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-400x228.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/clicked_on_number1-50x29.png 50w" sizes="(max-width: 2250px) 100vw, 2250px"></p>
<p>I can see the changes that developer (me) made to satisfy team lead&#x2019;s last comments on this MR. Those comments are shown in the middle of the screen. Let&#x2019;s assume that team lead is satisfied with the code and that I&#x2019;ve asked developer to show the app running with <code>FEATURE-add-animation</code> branch code. Now we&#x2019;re getting to the point of resolving a merge request, but wait&#x2026;</p>
<p>Let&#x2019;s not forget my annotation labelled #2. If team lead was <em>not</em> satisfied at this point, I could ask developer for more changes via another comment. Developer could go off and write more code and then commit/push. Then team lead could review the new code and&#x2026; You now see how this could go on for awhile. Complex merge requests often take serious time. Anyway, back to where we were in the last paragraph&#x2026;</p>
<p>The first thing I want to do is type in a final comment and click the &#x201C;Resolve conversation&#x201D; button. Typing a comment is optional, but good practice. Note that in a larger pull request, there can be multiple conversations that I&#x2019;d need to resolve. Here&#x2019;s what team lead me did:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15053" src="https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1466" height="840" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve.png 1466w, https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve-200x115.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve-524x300.png 524w, https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve-768x440.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve-1024x587.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve-1240x711.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve-860x493.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve-680x390.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve-400x229.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/comment_and_resolve-50x29.png 50w" sizes="(max-width: 1466px) 100vw, 1466px"></p>
<p>I now go to the &#x201C;Conversation&#x201D; tab and scroll down to what I showed you in the previous section: the image annotated with the #3. Let&#x2019;s say the team is ready to move the code in this MR into production. So I click that big green &#x201C;Merge pull request&#x201D; button. If there were merge conflicts, of course team lead me would resolve them before merging, but this screen says:</p>
<blockquote><p>This branch has no conflicts with the base branch<br>
Merging can be performed automatically.</p></blockquote>
<p>To confirm the merge, GitHub shows me this:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15061" src="https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master.png" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="1404" height="162" srcset="https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master.png 1404w, https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master-200x23.png 200w, https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master-600x69.png 600w, https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master-768x89.png 768w, https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master-1024x118.png 1024w, https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master-1240x143.png 1240w, https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master-860x99.png 860w, https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master-680x78.png 680w, https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master-400x46.png 400w, https://www.appcoda.com/content/images/wordpress/2019/04/merged_into_master-50x6.png 50w" sizes="(max-width: 1404px) 100vw, 1404px"></p>
<h2>Finishing up</h2>
<p>The <em>master</em> branch now contains the code that was requested to be written by team lead me with my directive to developer me to spice up our team&#x2019;s temperature app with animation. It&#x2019;s up to the team and/or project standard operating procedures as to whether to save or delete the feature branch (<code>FEATURE-add-animation</code>), including the remote and possibly many local copies. I usually keep feature or defect branches around for awhile, but clean them up eventually. The code contained in such branches can be useful. You&#x2019;ll understand when you start using merge requests.</p>
<p>Now anyone who pulls <em>master</em> or creates a new feature or defect branch will be getting the latest code with the desired level of animation:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-15057" src="https://www.appcoda.com/content/images/wordpress/2019/04/final_animate.gif" alt="How to Use Git Pull Requests to Improve Code Quality and Developer Participation" width="326" height="414"></p>
<h2>Conclusion</h2>
<p>Before merge requests, Git flows across the software industry tended to vary widely. They still do vary, and variety is good, because there is no &#x201C;perfect&#x201D; flow that fits all projects and organizations.</p>
<p>But by creating a formal flow by which, for example, developers can pick Scrum-based stories or defect reports and start working on them and tracking them each with a specific merge request, we&#x2019;ve come a long way in reining in the chaos that more informal Git flows can engender.</p>
<p>If you&#x2019;re working on a mid- to large-sized project that has no formal Git flow, I would suggest you look at merge requests.</p>
<h3>Suggested reading</h3>
<p>Here are some great articles you can read to help you get up to speed on merge requests:</p>
<p><a href="https://docs.gitlab.com/ee/user/project/merge_requests/?ref=appcoda.com">https://docs.gitlab.com/ee/user/project/merge_requests/</a><br>
<a href="https://www.atlassian.com/git/tutorials/making-a-pull-request?ref=appcoda.com">https://www.atlassian.com/git/tutorials/making-a-pull-request</a><br>
<a href="https://help.github.com/en/articles/about-pull-requests?ref=appcoda.com">https://help.github.com/en/articles/about-pull-requests</a><br>
<a href="https://help.github.com/en/articles/creating-a-pull-request?ref=appcoda.com">https://help.github.com/en/articles/creating-a-pull-request</a><br>
<a href="https://help.github.com/en/articles/viewing-deployment-activity-for-your-repository?ref=appcoda.com">https://help.github.com/en/articles/viewing-deployment-activity-for-your-repository</a><br>
<a href="https://help.github.com/en/articles/merging-a-pull-request?ref=appcoda.com">https://help.github.com/en/articles/merging-a-pull-request</a><br>
<a href="https://help.github.com/en/articles/about-required-status-checks?ref=appcoda.com">https://help.github.com/en/articles/about-required-status-checks</a><br>
<a href="https://help.github.com/en/articles/closing-issues-using-keywords?ref=appcoda.com">https://help.github.com/en/articles/closing-issues-using-keywords</a><br>
<a href="https://help.github.com/en/articles/requesting-a-pull-request-review?ref=appcoda.com">https://help.github.com/en/articles/requesting-a-pull-request-review</a><br>
<a href="https://help.github.com/en/articles/about-pull-request-reviews?ref=appcoda.com">https://help.github.com/en/articles/about-pull-request-reviews</a></p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[How to Use Xcode Instrument to Optimize Your Swift Code]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>I still run across curmudgeons who flat out reject techniques like object-oriented programming (especially inheritance and polymorphism), protocols and <a href="https://www.appcoda.com/pop-vs-oop/">protocol-oriented programming</a> (especially composition), generics, and closures. On a conscious level, the curmudgeons usually reject these technique because of their supposed &#x201C;massive&#x201D; performance cost. On a subconscious level, the</p>]]></description><link>https://www.appcoda.com/xcode-instrument/</link><guid isPermaLink="false">66612a0f166d3c03cf011487</guid><category><![CDATA[Xcode]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Tue, 30 Oct 2018 11:20:57 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2018/10/artem-sapegin-176819-unsplash.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->
<img src="https://www.appcoda.com/content/images/wordpress/2018/10/artem-sapegin-176819-unsplash.jpg" alt="How to Use Xcode Instrument to Optimize Your Swift Code"><p>I still run across curmudgeons who flat out reject techniques like object-oriented programming (especially inheritance and polymorphism), protocols and <a href="https://www.appcoda.com/pop-vs-oop/">protocol-oriented programming</a> (especially composition), generics, and closures. On a conscious level, the curmudgeons usually reject these technique because of their supposed &#x201C;massive&#x201D; performance cost. On a subconscious level, the curmudgeons don&#x2019;t understand these technologies. So do we give up all hope or do we accept the fact that compiler designers have come up with brilliant optimizations that ameliorate the use of such high-level technologies? We should believe in Swift&#x2019;s compiler designers. Do we realize that there are great tools like Xcode Instruments that help us find awkward implementations of these techniques and give us the opportunity to come up with our own optimizations? Yes.</p>
<p>There are costs to these high-level features, but I would argue that in most cases, language compiler optimizations, operating systems enhancements, and faster hardware (like solid state drives and multi-core processors), make up for the costs. Sure, once in a while you&#x2019;ll have a use case where advanced code features don&#x2019;t pay off, i.e., code is badly written or not used for the intended purpose.</p>
<p>Most of the time, these advanced features save software development boutiques enormous amounts of time and resources. Advanced language features usually let us do more by writing less and very expressive code. Time is saved because team members can easily read each other&#x2019;s semantically clear code. Since the code is readable and logically organized, it can be extended, reused, debugged, and maintained easily.</p>
<p>But by goodness, nobody&#x2019;s perfect, not even me ;-). Software keeps getting more and more complex. Users keep demanding more, better, and faster features. Problems will occur. Some apps are so slow that people just delete them.</p>
<p>Do we find out why our apps are so slow by using just <code>print</code> statements and breakpoints? I hope not, but I&#x2019;ve seen more than a fair share of Stone Age &#x201C;optimization&#x201D; techniques. No. We turn to the darn good tools that <em>already</em> come bundled <em>free</em> with Xcode.</p>
<h2>Using Xcode Instruments to Identify Performance Problems</h2>
<p>The Xcode Instruments&#x2019; <em>Time Profiler</em> template is the best template to start with when looking for app performance problems and/or determining how to improve performance. According to Apple, the <em>Time Profiler</em> template &#x201C;performs low-overhead time-based sampling of processes running on the system&#x2019;s CPUs.&#x201D;</p>
<p>We&#x2019;re going to use the <em>Time Profiler</em> to analyze the performance of my sample app&#x2019;s code. Please download it from <a href="https://github.com/appcoda/XcodeInstrument?ref=appcoda.com">GitHub</a>. In simplest of terms, <em>Time Profiler</em> collects information about your app while it&#x2019;s running, determines how long each of your functions takes to run, and also figures out the percentage of CPU cycles each of your functions is using. It gathers the same data about iOS SDK functions. The percentage of CPU cycles from 0% to 100% at each sample point is shown over time on a graph called the &#x201C;timeline&#x201D; or &#x201C;track.&#x201D; There are multiple tracks. The top track aggregates all the data from all individual thread and CPU core tracks. The <em>Time Profiler</em> is a very powerful tool as it shows your app&#x2019;s performance in real time, thus reflecting surges or lulls in CPU usage. We&#x2019;ll walk through an example.</p>
<h3>Your Profiling Environment</h3>
<p>Before we begin, realize that, when profiling your code, especially when comparing two different approaches to the same problem, <strong>it&#x2019;s imperative that you compare apples and apples, not apples and bananas</strong>. In other words, if you&#x2019;re profiling an algorithm and trying to optimize it, you want to <strong>use the same device (or simulated device) with the same configuration</strong>.</p>
<p>When I compared the performance of functions <code>showEmployee()</code> and <code>show()</code> from my sample app in the demo below, I ran and profiled each method on the <strong>same iPhone 8, with the same configuration</strong>. When preparing my iPhone 8 for profiling, I first shut down all running apps. Since the code I was studying didn&#x2019;t involve any type of connectivity, I shut down WiFi, Bluetooth, and cellular. Of course, if you&#x2019;re profiling networking code, like communications with a REST API, you&#x2019;ll need to have WiFi or cellular.</p>
<p>The key takeaway here is that <strong>you want to minimize, preferably eliminate, the number of (random) variables that may skew <em>Time Profiler</em> analysis and results</strong>. Imagine if you&#x2019;re profiling an algorithm and your iPhone starts up <a href="https://www.imore.com/how-to-manage-background-app-refresh-iphone-ipad?ref=appcoda.com"><em>Background App Refresh</em></a>&#x2026; Your analysis may be tainted &#x2014; artificially skewed so that you believe your algorithm is slower than it really should be. Imagine if you profile one algorithm when nothing is running in the background on your iPhone, profile a similar algorithm while your iPhone performs a background refresh, and then compare the two results (data sets). Is this a meaningful comparison?</p>
<h3>Using Instruments&#x2019; <em>Time Profiler</em> Template</h3>
<p>Let&#x2019;s walk through the profiling of my &#x201C;Optimizing Swift Code&#x201D; <a href="https://github.com/appcoda/XcodeInstrument?ref=appcoda.com">sample project</a>. Open the project in Xcode. Click and hold the <em>Build</em> and then run the <em>current scheme</em> button until you see the down arrow. Click the down arrow and then select the <em>Profile</em> option from the context menu, like so:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14303" src="https://www.appcoda.com/content/images/wordpress/2018/10/1-Start-Profile.gif" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="412" height="210"></p>
<p>The <em>Choose a profiling template for:</em> dialog will open. Select the <em>Time Profiler</em> template and click the <em>Choose</em> button:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14304" src="https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-1024x581.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="1024" height="581" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-1024x581.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-200x113.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-529x300.png 529w, https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-768x436.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-1240x703.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-860x488.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-680x386.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-400x227.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template-50x28.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/2-Choose-Template.png 1548w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>The <em>Time Profiler</em> template window will open, ready to sample and render performance data of my &#x201C;Optimizing Swift Code&#x201D; app. I&#x2019;ll refer to the following image as the &#x201C;map:&#x201D;</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14305" src="https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-1024x671.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="1024" height="671" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-1024x671.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-200x131.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-458x300.png 458w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-768x503.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-1680x1101.png 1680w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-1240x813.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-860x564.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-680x446.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-400x262.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview-50x33.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/3-Time-Profiler-Overview.png 1810w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>I&#x2019;ve numbered my annotations to correspond with the general sequence of the workflow you use to analyze app performance. I&#x2019;ll also refer to these annotations in the following discussion.</p>
<p>To begin profiling, press the record toggle button &#x2014; what I call the &#x201C;1 &#x2013; Start/Stop&#x201D; (map) button:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14306" src="https://www.appcoda.com/content/images/wordpress/2018/10/4-Start-Recording.gif" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="682" height="366"></p>
<p>When you feel you&#x2019;ve sampled enough data, press the &#x201C;2 &#x2013; Pause&#x201D; button or &#x201C;1 &#x2013; Start/Stop&#x201D; toggle (see map). Now it&#x2019;s time to examine the profile (sample data collected). Since I&#x2019;m running code in the background via <a href="http://iosbrain.com/blog/2018/03/07/concurrency-in-ios-serial-and-concurrent-queues-in-grand-central-dispatch-gcd-with-swift-4/?ref=appcoda.com">GCD</a>, I can scroll down to see activity per thread and per core:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14307" src="https://www.appcoda.com/content/images/wordpress/2018/10/5-Scroll-Profile.gif" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="682" height="366"></p>
<h3>Analyzing Your Profile</h3>
<p>Now it&#x2019;s time to analyze the recorded profile data. You generally start by clicking into an area of activity on the track/timeline or by highlighting a &#x201C;slice&#x201D; of the timeline. Remember that you can not only look at the top/aggregate track, but also inspect each thread or core:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14308" src="https://www.appcoda.com/content/images/wordpress/2018/10/6-Select-Track.gif" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="682" height="366"></p>
<p>When you click on a single time/data sample or highlight a slice, the corresponding code executing at that time of that selection is shown in what I annotated on my map as the &#x201C;4 &#x2013; Heaviest Stack Trace,&#x201D; &#x201C;5.1 &#x2013; Stack trace of method names (tree),&#x201D; and &#x201C;5.2 &#x2013; Measures of CPU used.&#x201D; You all should know that functions are pushed on and popped off the stack, that functions calling other functions builds a stack trace, and that &#x201C;Heaviest Stack Trace&#x201D; means high CPU usage (cycles).</p>
<div class="alert green">
<strong>IMPORTANT NOTE:</strong> If you&#x2019;ve found that there&#x2019;s some bottleneck in your app, but you don&#x2019;t know where exactly it resides in your code, look for:<br>
&#x2013; functions in the &#x201C;Heaviest Stack Trace&#x201D; pane; and/or,<br>
&#x2013; thick, high, and blue activity on the top track, or possibly in thread and core tracks.
</div>
<p>I&#x2019;m interested in two regions on the timeline. Why? because they show non-trivial CPU activity:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14312" src="https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="610" height="230" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest.png 610w, https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest-200x75.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest-600x226.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest-400x151.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest-50x19.png 50w" sizes="(max-width: 610px) 100vw, 610px"></p>
<p>After I&#x2019;ve selected a slice of the timeline, here &#x201C;Region 1,&#x201D; I first look at the &#x201C;4 &#x2013; Heaviest Stack Trace&#x201D; pane (see map) for method names I recognize with a person icon next to them. The person icon indicates my code; other icons represent iOS calls. The &#x201C;4 &#x2013; Heaviest Stack Trace&#x201D; pane shows me code with high CPU usage.</p>
<p>In <em>this case</em>, I also expected to see certain functions at startup; code that I wrote. I know my own code. I clicked on one of my method names in &#x201C;4 &#x2013; Heaviest Stack Trace&#x201D; so that its stack trace and symbols (function/class/struct names) would be shown in the &#x201C;5.1 &#x2013; Stack trace of method names (tree)&#x201D; and &#x201C;5.2 &#x2013; Measures of CPU used&#x201D; pane (see map):</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-14310 size-large" src="https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-1024x342.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="1024" height="342" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-1024x342.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-200x67.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-600x200.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-768x256.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-1680x560.png 1680w, https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-1240x414.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-860x287.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-680x227.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-400x133.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/createEmployees-50x17.png 50w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Notice all the detail. And notice that I can expand a symbol (function) name to see everything being called by it. If you go into my &#x201C;Optimizing Swift Code&#x201D; project, you can see how the <code>Organization.createEmployees()</code> method is called at app startup. Look in project file <code>Organization.swift</code> and you&#x2019;ll find this code:</p>
<pre class="swift">import Foundation

class Organization {
    
    var employees: [Employee] = []
    
    func createEmployees() {
        
        for count in 1...count {
            
            let employeeID = &quot;employee&quot; + String(count)
            let age = Int(arc4random_uniform(47)) + 18
            
            let employee = Employee(firstName: &quot;first&quot;+String(count), lastName: &quot;last&quot;+String(count), age: age, streetAddress: String(count)+&quot; Main St&quot;, zip: &quot;90210&quot;, employeeID: employeeID)
            
            employees.append(employee)
            
            print(&quot;Employee \(count) created.&quot;)
            
        } // end while
                
    } // end func createEmployees()
    
} // end class Organization
</pre>
<p><em>But</em>&#x2026; I don&#x2019;t have to switch to Xcode to look at my code.</p>
<p>If I double-click on the symbol <code>Organization.createEmployees()</code> in the &#x201C;5.1 &#x2013; Stack trace of method names (tree)&#x201D; and &#x201C;5.2 &#x2013; Measures of CPU used&#x201D; pane, I jump right to the source code:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14311" src="https://www.appcoda.com/content/images/wordpress/2018/10/JumpToSource.gif" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="890" height="474"></p>
<p>You see that Instruments provides annotations (metrics) on performance (like the yellow arrow marked &#x201C;47x&#x201D;), but suppose you want <em>serious detail</em>, like assembly code. Click on the <em>Show side-by-side source/disassembly view</em> button:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14316" src="https://www.appcoda.com/content/images/wordpress/2018/10/SideBySide.gif" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="1024" height="454"></p>
<p>Look at all that information. You can even see <a href="http://iosbrain.com/blog/2018/06/07/swift-4-memory-management-via-arc-for-reference-types-classes/?ref=appcoda.com">ARC memory management</a> in action, like retain and release statements. Note that ARC has overhead, so when using classes (reference types), you may have to carefully architect your code &#x2014; and possibly optimize it.</p>
<p>Now that you have an idea of how the Instruments&#x2019; <em>Time Profiler</em> template works, let&#x2019;s look at optimizing some Swift code.</p>
<h2>Optimizing Swift Code</h2>
<p>Those busy Swift compiler engineers have done a great job of making Swift fast and light-weight. Back in Swift 2.0, there were more opportunities for <em>developers using the language</em> to optimize their code. With the release of Swift 4.2, the compiler is pretty darn optimized &#x2014; but that doesn&#x2019;t prevent people from writing bad code. Still, developers need to legitimately optimize code, especially code in which there are complex relationships, mountains of data, and/or extensive calculations.</p>
<h3>Dynamic Dispatch</h3>
<p>Let&#x2019;s look at an example involving dynamic dispatch. I urge you to pause at some point while reading this article to take a look at an excellent Apple Developer blog post entitled <a href="https://developer.apple.com/swift/blog/?id=27&amp;ref=appcoda.com">&#x201C;Increasing Performance by Reducing Dynamic Dispatch&#x201D;</a>. You should understand dynamic dispatch by now, even the Swifties, but especially if you used to develop in Objective-C.</p>
<p>My sample code is not Earth-shatteringly innovative, it&#x2019;s not supposed to be. I&#x2019;m using a simple example so you can understand the language concepts and optimization tools.</p>
<p>Remember &#x201C;Region 2&#x201D; in my <em>Time Profiler</em> trace? Here&#x2019;s a reminder:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14312" src="https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="610" height="230" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest.png 610w, https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest-200x75.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest-600x226.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest-400x151.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/RegionsOfInterest-50x19.png 50w" sizes="(max-width: 610px) 100vw, 610px"></p>
<p>Let&#x2019;s look at what Instruments showed me when I selected a slice of this part of the timeline:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14317" src="https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-1024x389.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="1024" height="389" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-1024x389.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-200x76.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-600x228.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-768x292.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-1680x638.png 1680w, https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-1240x471.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-860x327.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-680x258.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-400x152.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/startButtonTapped-50x19.png 50w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Hmmm&#x2026; I see <code>ViewController.startButtonTapped(_:)</code>, which is close, but I&#x2019;m not seeing what I&#x2019;m interested in. (That&#x2019;s because this is a simple example, I&#x2019;m running code in the background using <a href="http://iosbrain.com/blog/2018/03/07/concurrency-in-ios-serial-and-concurrent-queues-in-grand-central-dispatch-gcd-with-swift-4/?ref=appcoda.com">GCD</a>, and therefore iOS is using as many threads/cores as necessary to keep my app responsive.)</p>
<p>I&#x2019;m comparing the performance of two methods, <code>showEmployee()</code> and <code>show()</code>. See file <code>ViewController.swift</code> in my &#x201C;Optimizing Swift Code&#x201D; sample project:</p>
<pre class="swift">    @IBAction func startButtonTapped(_ sender: Any) {
        
        while true {
            
            DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
                
                for count in 0...count-1 { // 0...999999
                    
                        //let employeeInfo = self.organization.employees[count].showEmployee()
                        let employeeInfo = self.organization.employees[count].show()
                    
                        DispatchQueue.main.async {

                            self.newEmployeesTextView.text += employeeInfo
                            print(&quot;\(employeeInfo)\n&quot;)
                            
                        }
                    
                } // end for count in 0...count-1
                
            } // end DispatchQueue.global
            
        } // end while true

    } // end func startButtonTapped
</pre>
<p>Remember &#x201C;6 &#x2013; Find symbols&#x201D; in my map? I ran multiple profiling sessions, several to investigate <code>showEmployee()</code> and several for <code>show()</code>. Hey, call me a stickler for details, but I don&#x2019;t trust one data sample. I&#x2019;ve got two math minors with an emphasis on statistics, so yes, I profiled multiple times to make sure my claims were substantiated. I&#x2019;ll present two representative samples from my research (and yes, I switched out of dark mode because my eyes were getting tired).</p>
<p>Here&#x2019;s what I found out about the performance of <code>Employee.show()</code>:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14314" src="https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-1024x333.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="1024" height="333" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-1024x333.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-200x65.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-600x195.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-768x250.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-1680x547.png 1680w, https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-1240x404.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-860x280.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-680x221.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-400x130.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/show-Core2-50x16.png 50w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Here&#x2019;s what I found out about the performance of <code>Employee.showEmployee()</code>:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14315" src="https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-1024x334.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="1024" height="334" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-1024x334.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-200x65.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-600x196.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-768x251.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-1680x548.png 1680w, https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-1240x405.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-860x281.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-680x222.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-400x131.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/showEmployee-Core2-50x16.png 50w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>What I found was that <code>Employee.showEmployee()</code> is conservatively about 2.5 times faster than <code>Employee.show()</code>. Yes, I know&#x2026; Is saving less than a millisecond really an optimization? In this app, no. If you&#x2019;re working on some app that repeats a call millions of times, maybe optimization by taking out dynamic dispatch would be worth your effort.</p>
<p>So why is <code>Employee.showEmployee()</code> faster? Let&#x2019;s look into the code. First, look in file <code>People.swift</code>:</p>
<pre class="swift">import Foundation

class Person {
    
    /*
     final var firstName: String
     final var lastName: String
     final var age: Int
     final var streetAddress: String
     final var zip: String
    */
    var firstName: String
    var lastName: String
    var age: Int
    var streetAddress: String
    var zip: String
    
    init(firstName: String,
         lastName: String,
         age: Int,
         streetAddress: String,
         zip: String) {
        
        self.firstName = firstName
        self.lastName = lastName
        self.age = age
        self.streetAddress = streetAddress
        self.zip = zip
        
    }
    
    func show() -&gt; String {
        let line = &quot;&quot;&quot;
        First name: \(firstName)
        Last name: \(lastName)
        Age: \(age)
        Street Address: \(streetAddress)
        Zip Code: \(zip)
        &quot;&quot;&quot;
        
        return line
    }
    
} // end class Person
</pre>
<p>Notice method <code>show()</code> above. It is overriden in file <code>Employees.swift</code>, shown here:</p>
<pre class="swift">import Foundation

class Employee: Person {
    
    var employeeID: String
    var retirementAge: Int = 60
    
    init(firstName: String,
         lastName: String,
         age: Int,
         streetAddress: String,
         zip: String,
         employeeID: String) {
        
        self.employeeID = employeeID
        super.init(firstName: firstName, lastName: lastName, age: age, streetAddress: streetAddress, zip: zip)
    }
    
    func isRetirementReady() -&gt; Bool {
        if age &gt;= retirementAge {
            return true
        }
        else {
            return false
        }
    }
    
    override func show() -&gt; String {
        var line = super.show()
        line += &quot;Employee ID: \(employeeID)\n&quot;
        line += &quot;Retirement Age: \(retirementAge)&quot;
        return line
    }
    
    final func showEmployee() -&gt; String {
        let line = &quot;&quot;&quot;
        First name: \(firstName)
        Last name: \(lastName)
        Age: \(age)
        Street Address: \(streetAddress)
        Zip Code: \(zip)
        Employee ID: \(employeeID)
        Zip Code: \(zip)
        &quot;&quot;&quot;
        
        return line

    }
    
}  // end class Employee
</pre>
<p>Notice that I&#x2019;ve indulged in some overkill here to make a point. Not only have I completely rewritten the <code>show()</code> methods in the form of <code>showEmployee()</code>, but I&#x2019;ve also marked <code>showEmployee()</code> as <code>final</code> which <a href="https://developer.apple.com/swift/blog/?id=27&amp;ref=appcoda.com">&#x201C;allows the compiler to safely elide dynamic dispatch indirection.&#x201D;</a></p>
<h3>Whole Module Optimization</h3>
<p>Remember earlier that I said that the Swift compiler is getting really smart? <strong>As I understand it, the optimizations that I&#x2019;ll discuss from here onwards are already turned on by default. Even so, I believe it&#x2019;s instructive and helpful for you to understand what the Swift compiler is doing with your code.</strong></p>
<p>Look at the default Xcode 10 <em>Build Settings</em> under <em>Swift Compiler &#x2013; Code Generation</em>:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14309" src="https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings-1024x470.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="1024" height="470" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings-1024x470.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings-200x92.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings-600x275.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings-768x353.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings-860x395.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings-680x312.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings-400x184.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings-50x23.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/CompilerBuildSettings.png 1220w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Notice that <em>Compilation Mode</em> is set to <em>Incremental</em> for <em>Debug</em> and that <em>Optimization Level</em> is set to <em>No Optimization</em> for <em>Debug</em>. These settings make for fast build times. It should be obvious why performing no optimizations is faster. Incremental building means only recompiling files that have changed since the last build, accounting for updated dependencies. Finally, the Swift compiler <a href="https://developer.apple.com/videos/play/wwdc2015-409/?time=402&amp;ref=appcoda.com">&#x201C;can compile many files in parallel on multiple cores in your machine.&#x201D;</a></p>
<p><em>Compilation Mode</em> is set to <em>Whole Module</em> for <em>Release</em>. <em>Optimization Level</em> is set to <em>Optimize for Speed</em> for <em>Release</em>. That makes for fast apps that you publicly distribute.</p>
<p>I made it a point to break my code into as many logical modules as possible in my &#x201C;Optimizing Swift Code&#x201D; sample project:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14313" src="https://www.appcoda.com/content/images/wordpress/2018/10/SeparateFiles.png" alt="How to Use Xcode Instrument to Optimize Your Swift Code" width="616" height="612" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/SeparateFiles.png 616w, https://www.appcoda.com/content/images/wordpress/2018/10/SeparateFiles-200x199.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/SeparateFiles-302x300.png 302w, https://www.appcoda.com/content/images/wordpress/2018/10/SeparateFiles-400x397.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/SeparateFiles-50x50.png 50w" sizes="(max-width: 616px) 100vw, 616px"></p>
<p>Profiling this and many other projects for customers, I&#x2019;ve seen <a href="https://developer.apple.com/swift/blog/?id=27&amp;ref=appcoda.com">Whole Module Optimization</a> speed up my <em>public releases</em>. In fact, the changes I made to enhance performance in the previous section were done in <em>Debug</em>. When I removed the <em>final</em> keyword in <em>Release</em>, my profiling seemed to confirm that the Swift compiler inferred it as an optimization.</p>
<div class="alert grey">
<strong>NOTE:</strong> You should still consider applying the `final` keyword to both class properties and methods when performance is critical. You can always use Instruments to determine if your &#x201C;optimizations&#x201D; are indeed optimizations.
</div>
<p>There&#x2019;s one language feature where Whole Module Optimization has an additive effect on another one. We&#x2019;ll discuss this in the next section.</p>
<h3>Generics</h3>
<p>Think about a generic function like the one included with my sample app. You&#x2019;ll find it in <code>Generics.swift</code>:</p>
<pre class="swift">func exists&lt;T: Equatable&gt;(item:T, inArray:[T]) -&gt; Bool {

    var index:Int = 0
    var found = false
    
    while (index &lt; inArray.count &amp;&amp; found == false)
    {
        if item == inArray[index]
        {
            found = true
        }
        else
        {
            index = index + 1
        }
    }
    
    if found
    {
        return true
    }
    else
    {
        return false
    }
    
} // func exists
</pre>
<p>The compiler looks at this function and realizes that <a href="https://developer.apple.com/videos/play/wwdc2015-409/?time=1076&amp;ref=appcoda.com">&#x201C;it must be able to handle any type T&#x201D;</a> that conforms to <code>Equatable</code>. Think about the complexities involved in generics. You&#x2019;re writing code that ideally should be able to handle <em>any</em> type.</p>
<p>Swift already supports an optimization called <a href="https://developer.apple.com/videos/play/wwdc2015-409/?time=1086&amp;ref=appcoda.com"><em>generic specialization</em></a>. It turns out that Whole Module Optimization <a href="https://developer.apple.com/videos/play/wwdc2015-409/?time=1207&amp;ref=appcoda.com"><em>also</em> optimizes generics</a>. Why?</p>
<p>I know this is a relatively old video, but you should <a href="https://developer.apple.com/videos/play/wwdc2015/409/?ref=appcoda.com">watch the whole thing</a> to find out.</p>
<p>I proved to myself that Whole Module Optimization sped up calls in my sample project to my <code>exists</code> generic function. I profiled the project with Whole Module Optimization on and then profiled it with the setting turned off. This is how you learn about powerful tools.</p>
<h3>Simple Optimizations</h3>
<p>Say you&#x2019;re designing a data-intensive app and you need to pick the fastest data structures to use in your code. Go to a site like <a href="http://www.bigocheatsheet.com/?ref=appcoda.com">this one</a>, look at the Big-O complexity chart, review the data structures, and look at the time requirements of their operations. Then pick the data structures that balance your requirements with speed.</p>
<h3>ARC Memory Management</h3>
<p>ARC memory management has overhead, but I&#x2019;ve read multiple scientific and commercial journal articles that <strong>do not</strong> conclude that reference types and reference semantics are slower than value types and value semantics.</p>
<p>In my own work, I&#x2019;ve never been able to prove that, in general, one was faster than the other, as long as sound best practices were used in development across the board.</p>
<p>While writing this article, I actually coded an entire Swift project that performs the same task by <strong>1)</strong> entirely using reference types and semantics and <strong>2)</strong> entirely using value types and semantics. After multiple sessions with the <em>Time Profiler</em>, I couldn&#x2019;t find any significant difference between the two.</p>
<p>Nevertheless, I&#x2019;ve seen scenarios in which ARC <em>did</em> degrade performance when misused, for example, creating too many references, or using large numbers of reference types when value types could be used instead. One has to strike a balance. For example, if we replace a bunch of references with values, what happens when we have to constantly change and copy those values?</p>
<h2>Conclusion</h2>
<p>I encourage you to play with my project&#x2019;s Swift code and its <em>Swift Compiler &#x2013; Code Generation</em> settings &#x2014; and then practice with the <em>Time Profiler</em> to analyze and possibly optimize the code. If not my code, use your own code. But practice, practice, and practice with the <em>Time Profiler</em>.</p>
<p>You need to be able to <em>find</em> bottlenecks in your code and then be able to <em>optimize</em> them. You&#x2019;ll feel a bit overwhelmed if you&#x2019;ve never used Instruments before. I&#x2019;ve been using its templates for years and still find it a bit overwhelming. But <em>not</em> using Instruments is a travesty. It offers so many ways to solve problems more easily than using brute force.</p>
<p>By brute force, I mean only fixing bugs and making optimizations by using <code>print</code> statements and maybe some breakpoints.</p>
<p>Please don&#x2019;t give up on tools like object-oriented programming, protocols and protocol-oriented programming, generics, and closures just because you&#x2019;ve had a few bad experiences or because you heard they have &#x201C;high overhead.&#x201D; When used right, these tools can actually reduce the amount of code you write and <em>speed up</em> your apps. They can certainly help with code maintainability, readability, and reusability.</p>
<p>You have excellent tools with Xcode. <strong>Use them.</strong></p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Dividing and Conquering Your Xcode Projects with Targets]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>In this tutorial, I&#x2019;ll show you how to leverage Xcode <em>targets</em> to control the massive complexity involved in building iOS (and macOS, watchOS, and tvOS) apps. A lot of time can be saved when developers realize that not everything they&#x2019;re required to do has to be</p>]]></description><link>https://www.appcoda.com/xcode-targets/</link><guid isPermaLink="false">66612a0f166d3c03cf011486</guid><category><![CDATA[Xcode]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Thu, 25 Oct 2018 10:15:20 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2018/10/xcode-target-feature.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->
<img src="https://www.appcoda.com/content/images/wordpress/2018/10/xcode-target-feature.jpg" alt="Dividing and Conquering Your Xcode Projects with Targets"><p>In this tutorial, I&#x2019;ll show you how to leverage Xcode <em>targets</em> to control the massive complexity involved in building iOS (and macOS, watchOS, and tvOS) apps. A lot of time can be saved when developers realize that not everything they&#x2019;re required to do has to be done by writing software language code, like Swift. Integrated development environments (IDEs) like Xcode offer very powerful tools, like targets, that allow developers to decouple nitty-gritty tasks that used to be done in code (or manually) out into project configuration settings. I&#x2019;ve found that, because of the sheer number of project settings, developers often take one look at say, Xcode&#x2019;s long, long list of <em>Build Settings</em>, and want to curl up and pass out. When finished reading this tutorial, you&#x2019;ll see that you can <em>neatly</em> organize code into <em>one</em> project that&#x2019;s capable of producing binaries for iOS, macOS, watchOS, and tvOS.</p>
<p>If developers take the time to harness the power of Xcode&#x2019;s features, they can spend most of their time doing what they should be doing: designing, writing, and organizing their code using tools like architectural design patterns (MVVM), tactical design patterns (factory method, facade, adapter), object-oriented techniques, protocol-oriented techniques, generics, delegation &#x2014; all good, solid <em>development</em> concepts.</p>
<p>Developers should always be on the lookout for opportunities to <em>logically</em> organize and group related code and, conversely, <em>logically</em> separate unrelated code. Xcode targets can let you take related code, put it into one project, yet simultaneously target that code at each of Apple&#x2019;s platforms: iOS, macOS, watchOS, and tvOS.</p>
<p>When it comes to the more mundane tasks, like changing an app&#x2019;s name, version number, help bundle, app icon, or copyright text, programmers should be able to turn to Xcode&#x2019;s tools. Developers <em>shouldn&#x2019;t</em> be dealing with such tasks using hacks, pyramid-of-doom <code>if</code> statements, and hardcoding values and/or logic. Let&#x2019;s decouple our coding from these usually boring but necessary responsibilities. Targets help here.</p>
<p>The protocol I&#x2019;ll discuss herein is a mixture of using Xcode &#x201C;targets&#x201D; and &#x201C;schemes.&#x201D; I&#x2019;m sure all sorts of people have all sorts of ways of doing things differently, but I&#x2019;ve found that this works best for me. I&#x2019;m not claiming this is the <em>only</em> way to do things.</p>
<p>I know I could&#x2019;ve (possibly) made things even more generalized by using workspaces, but this is a tutorial. You need to grasp the basics of Xcode&#x2019;s targets and schemes before building a better, newer, grander solution. There&#x2019;s such a thing as being <em>too generalized</em> to be useful, too&#x2026;</p>
<h2>Introduction to Xcode Targets</h2>
<p>When you create a new project in Xcode, <a href="https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/WorkingwithTargets.html?ref=appcoda.com#//apple_ref/doc/uid/TP40010215-CH32-SW1">one single target</a> is created for you. For example, I created an Xcode project for iOS, based on the <em>Single View App</em> template, and named it &#x201C;Xcode Targets.&#x201D; You can download it from <a href="https://github.com/appcoda/Xcode-Targets/tree/master/Xcode%20Targets?ref=appcoda.com">GitHub</a>. Let&#x2019;s get a quick overview of how project configuration settings/options are stored.</p>
<p>According to the <a href="https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/CreatingProjects.html?ref=appcoda.com#//apple_ref/doc/uid/TP40010215-CH31-SW1">Xcode docs</a>,</p>
<blockquote><p>By selecting the project name in the project navigator, you open the project editor.</p></blockquote>
<p>Let&#x2019;s do that and here&#x2019;s what we&#x2019;ll see:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14268" src="https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview-1024x458.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="458" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview-1024x458.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview-200x89.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview-600x268.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview-768x344.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview-860x385.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview-680x304.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview-400x179.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview-50x22.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/XcodeOverview.png 1140w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>As we forge ahead through this tutorial, keep two concepts from the Xcode docs in mind. First, <a href="https://web.archive.org/web/20160315051113/https://developer.apple.com/library/ios/recipes/xcode_help-project_editor/Articles/BasingBuildConfigurationsonConfigurationFiles.html">consider that</a>:</p>
<blockquote><p>Build settings defined at the target level override any values assigned to those build settings at the project level. Therefore, target-level configurations take precedence over any project-level configurations.</p></blockquote>
<p>Second, <a href="https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/WorkingwithTargets.html?ref=appcoda.com#//apple_ref/doc/uid/TP40010215-CH32-SW1">recognize that</a>:</p>
<blockquote><p>A target contains instructions&#x2013;in the form of build settings and build phases&#x2013;for building a product. A target inherits the project&#x2019;s build settings. Although most developers seldom need to change these settings, you can override any of the project&#x2019;s build settings by specifying different settings at the target level.</p></blockquote>
<p>You&#x2019;ll see that I generally disagree with the statement, &#x201C;Although most developers seldom need to change these settings.&#x201D; We&#x2019;ll be changing settings. That&#x2019;s a major concern in this tutorial.</p>
<h3>A note about &#x201C;configurations&#x201D;</h3>
<p>Apple <a href="https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/CreatingProjects.html?ref=appcoda.com#//apple_ref/doc/uid/TP40010215-CH31-SW1">notes that</a>:</p>
<blockquote><p>When you create a project, Xcode provides two standard project-level build configurations: debug and release. &#x2026; These two build configurations are probably sufficient for your product development needs. Most developers never need to change the values of the vast majority of build settings.</p></blockquote>
<p>I would add that you can change debug and release settings in each of your <em>targets</em>, not just at the project level. Perhaps because of the length of time that I&#x2019;ve developed Apple apps, and the complexity of most apps with which I&#x2019;ve worked, I find myself and coworkers often need to change the values of <em>Build Settings</em>. I also find it very confusing and difficult to manage when almost <em>every</em> build setting at the project and target level have a <code>Debug</code> and <code>Release</code> option. See the following image &#x2014; and remember that these are <em>just a few</em> of the available options:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14246" src="https://www.appcoda.com/content/images/wordpress/2018/10/DebugReleaseAdInfinitum.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="370" height="986" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/DebugReleaseAdInfinitum.png 370w, https://www.appcoda.com/content/images/wordpress/2018/10/DebugReleaseAdInfinitum-200x533.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/DebugReleaseAdInfinitum-113x300.png 113w, https://www.appcoda.com/content/images/wordpress/2018/10/DebugReleaseAdInfinitum-50x133.png 50w" sizes="(max-width: 370px) 100vw, 370px"></p>
<p>So when faced with debug/release, debug/release, debug/release, debug/release&#x2026;, I see the opportunity for developers to start unwittingly &#x2014; and easily &#x2014; commingling debug and release options, or just plain setting conflicting options. As we&#x2019;ll soon see, I&#x2019;d rather keep all my release settings in one target and my debug settings in another.</p>
<h2>Separating release settings from debug settings</h2>
<p>Once I&#x2019;ve created a project as described above, the first thing I do is to rename the default target as shown here:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14264" src="https://www.appcoda.com/content/images/wordpress/2018/10/RenameDefaultToRelease.gif" alt="Dividing and Conquering Your Xcode Projects with Targets" width="238" height="58"></p>
<p>Let me just briefly mention <em>schemes</em>. There are variety ways to approach organizing project settings, and I want to keep this tutorial simple. Let me just quote the <a href="https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/BuildingYourApp.html?ref=appcoda.com">Xcode documentation</a> again:</p>
<blockquote><p>When you open an existing project (or create a new one), Xcode automatically creates a scheme for each target. The default scheme is named after your project&#x2026;</p></blockquote>
<p>You can read up on schemes using the links I&#x2019;ve provided. Since a default scheme was generated when I created the project, I&#x2019;m going to rename it with the same name as my default target:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14263" src="https://www.appcoda.com/content/images/wordpress/2018/10/RenameDefaultScheme.gif" alt="Dividing and Conquering Your Xcode Projects with Targets" width="830" height="468"></p>
<p>Notice that I&#x2019;ve left the <em>Autocreate schemes</em> checkbox ticked.</p>
<p>Now let&#x2019;s set &#x201C;Xcode Targets &#x2013; Release&#x201D; scheme&#x2019;s <em>Build Configuration</em> to <code>Release</code> to match it&#x2019;s name. Go to the <em>Set the active scheme</em> control, just where we started in the last video, <em>Edit Scheme&#x2026;</em>, and change <code>Debug</code> to <code>Release</code> as follows:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14266" src="https://www.appcoda.com/content/images/wordpress/2018/10/SetRelSchemeToRel.gif" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="498"></p>
<p>Of course, now we want to create a new target (and scheme) for debugging. Here&#x2019;s how we create and rename a new target:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14247" src="https://www.appcoda.com/content/images/wordpress/2018/10/DuplicateDebugTarget.gif" alt="Dividing and Conquering Your Xcode Projects with Targets" width="314" height="140"></p>
<p>The <em>Autocreate schemes</em> checkbox had its intended effect, creating a new scheme &#x2014; <em>except</em> it didn&#x2019;t catch my renaming of my new target to &#x201C;Xcode Targets &#x2013; Debug.&#x201D; <em>Make sure</em> to change the newly auto-created scheme from &#x201C;Xcode Targets &#x2013; Release copy&#x201D; to &#x201C;Xcode Targets &#x2013; Debug&#x201D; just like how I did it in the gif above. Set &#x201C;Xcode Targets &#x2013; Debug&#x201D; scheme&#x2019;s <em>Build Configuration</em> to <code>Debug</code>. You may find that it is already set as <code>Debug</code>, but check it anyway.</p>
<p>To switch between debug and release configurations, all you have to do is switch/set the active scheme. <em>Very importantly</em>, make sure you confine all your <code>Release</code> configurations in <em>Build Settings</em> to the &#x201C;Xcode Targets &#x2013; Release&#x201D; target and all your <code>Debug</code> configurations in <em>Build Settings</em> to the &#x201C;Xcode Targets &#x2013; Debug&#x201D; target. We&#x2019;ll see how to do this below.</p>
<h3>A note about Info.plist</h3>
<p>When you <em>Duplicate</em> (create) a new target, Xcode creates a new <code>Info.plist</code>. It gives the new target a name you probably don&#x2019;t want and puts the file where you probably don&#x2019;t want:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14256" src="https://www.appcoda.com/content/images/wordpress/2018/10/NewInfoPlistLocation.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="598" height="360" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/NewInfoPlistLocation.png 598w, https://www.appcoda.com/content/images/wordpress/2018/10/NewInfoPlistLocation-200x120.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/NewInfoPlistLocation-498x300.png 498w, https://www.appcoda.com/content/images/wordpress/2018/10/NewInfoPlistLocation-400x241.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/NewInfoPlistLocation-50x30.png 50w" sizes="(max-width: 598px) 100vw, 598px"></p>
<p>I like to use the <code>$(SRCROOT)</code> macro in my Xcode projects to standardize and organize my file locations. To keep things &#x201C;Xcodey,&#x201D; I set my <em>Build Settings</em> for my &#x201C;Xcode Targets &#x2013; Release&#x201D; target&#x2019;s <code>Info.plist</code> like so:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14262" src="https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist-1024x364.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="364" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist-1024x364.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist-200x71.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist-600x214.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist-768x273.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist-860x306.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist-680x242.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist-400x142.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist-50x18.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseTargetInfoPlist.png 1180w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>For my &#x201C;Xcode Targets &#x2013; Debug&#x201D; target, I put my <code>Info.plist</code> here:</p>
<pre class="swift">$(SRCROOT)/Xcode Targets/Debug/Info-Debug.plist
</pre>
<p>I highly recommend that you clean up your <em>Project Navigator</em> setup after making these changes. (I control-clicked the &#x201C;Xcode Targets&#x201D; folder in the <em>Project Navigator</em> and used the <em>Add Files to &#x201C;Xcode Targets&#x201D;&#x2026;</em> to context menu command.) Look at the sample project and you&#x2019;ll understand.</p>
<h3>Release versus debug dependencies</h3>
<p>I&#x2019;ve supported quite a few iOS and macOS Xcode apps that consume C++ libraries. In order to provide optimized production code, I only include release versions of libraries when distributing apps to the public. When developing and debugging, I want debug versions of libraries with all symbols linked into my apps so I can set breakpoints and step through code.</p>
<p>For production, I switch to my &#x201C;Xcode Targets &#x2013; Release&#x201D; target and drag <em>release</em> versions of libraries into <em>Build Phases</em> -&gt; <em>Link Binary With Libraries</em> like this:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14261" src="https://www.appcoda.com/content/images/wordpress/2018/10/ReleaseLibDrag.gif" alt="Dividing and Conquering Your Xcode Projects with Targets" width="658" height="190"></p>
<p>For debugging and development:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14245" src="https://www.appcoda.com/content/images/wordpress/2018/10/DebugLibDrag.gif" alt="Dividing and Conquering Your Xcode Projects with Targets" width="658" height="190"></p>
<p>Remember that if I&#x2019;m calling code from linked libraries, I&#x2019;ll need the paths to the header files (.h, .hpp). I usually specify those in <em>Build Settings</em> -&gt; <em>Search Paths</em> -&gt; <em>User Header Search Paths</em>:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14251" src="https://www.appcoda.com/content/images/wordpress/2018/10/HeaderSearchPaths.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="562" height="412" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/HeaderSearchPaths.png 562w, https://www.appcoda.com/content/images/wordpress/2018/10/HeaderSearchPaths-200x147.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/HeaderSearchPaths-409x300.png 409w, https://www.appcoda.com/content/images/wordpress/2018/10/HeaderSearchPaths-400x293.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/HeaderSearchPaths-50x37.png 50w" sizes="(max-width: 562px) 100vw, 562px"></p>
<p>If I am responsible for the library code and need to maintain it in Xcode, I can use the same separation of concerns structure outlined in this tutorial in my library projects. We&#x2019;ll see an example below.</p>
<p>Suppose I have release and debug versions of <a href="http://iosbrain.com/blog/2018/01/13/building-swift-4-frameworks-and-including-them-in-your-apps-xcode-9/?ref=appcoda.com">iOS frameworks</a>. For release, I simply click on my &#x201C;Xcode Targets &#x2013; Release&#x201D; target and drag the release framework version into <em>General</em> -&gt; <em>Embedded Binaries</em>. For debug, I simply click on my &#x201C;Xcode Targets &#x2013; Debug&#x201D; target and similarly drag the debug framework version into my target.</p>
<p>Release and debug dependencies are cleanly separated using my targets protocol. We&#x2019;ll talk more about dependencies later.</p>
<h2>Compilation conditions</h2>
<p>Those of us who used and/or are still using Objective-C are accustomed to leveraging symbols like <code>DEBUG</code> defined in Xcode under <em>Build Settings</em> -&gt; <em>Apple LLVM 9.0 &#x2013; Preprocessing</em> -&gt; <em>Preprocessor Macros</em>. If you want similar behavior in Swift, you need to use what Apple calls <a href="https://docs.swift.org/swift-book/ReferenceManual/Statements.html?ref=appcoda.com#ID539"><em>conditional compilation</em></a>:</p>
<blockquote><p>A conditional compilation block allows code to be conditionally compiled depending on the value of one or more compilation conditions.</p></blockquote>
<p>You can use any of the symbols listed in <a href="https://docs.swift.org/swift-book/ReferenceManual/Statements.html?ref=appcoda.com#ID539">this link</a>, but I&#x2019;ll talk about using custom symbols here. Swift still respects <code>DEBUG</code>, but if you want to use it, or the language&#x2019;s built-in symbols, or custom symbols, you have to define them in your <em>Build Settings</em> -&gt; <em>Swift Compiler &#x2013; Custom Flags</em> -&gt; <em>Active Compilation Conditions</em> now.</p>
<p>Let&#x2019;s say I&#x2019;m logging (<code>LOG</code>) in release to create an audit trail (i.e., I&#x2019;m tracking logins). Check what&#x2019;s in my &#x201C;Xcode Targets &#x2013; Release&#x201D; target:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14260" src="https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease-1024x341.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="341" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease-1024x341.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease-200x67.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease-600x200.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease-768x256.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease-860x286.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease-680x226.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease-400x133.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease-50x17.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcRelease.png 1118w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Let&#x2019;s say I&#x2019;m not worried about auditing during development. Check what&#x2019;s in my &#x201C;Xcode Targets &#x2013; Debug&#x201D; target:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14259" src="https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug-1024x341.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="341" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug-1024x341.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug-200x67.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug-600x200.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug-768x256.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug-860x286.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug-680x226.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug-400x133.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug-50x17.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/PreProcDebug.png 1118w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>I&#x2019;ve supported quite a few iOS and macOS Xcode projects that consume C++ code that runs on multiple platforms, including Unix/Linux flavors, Microsoft Windows, and macOS. Sometimes things get tricky and, for example, I run into code that will only compile and run on Windows, but not on Mac, and vice versa. I try to minimize such situations, but sometimes things just need to get done. When necessary, I use preprocessor macros or, as Apple now says in Swift, <em>compilation conditions</em>, like <code>WIN</code>, <code>MAC</code>, <code>LOG</code>, and <code>DEBUG</code>.</p>
<p>When calling into my portable C++ code, something like <code>MAC</code> would be defined in both release and debug versions so that I can selectively compile, or <em>not</em> compile, portable or non-portable core code that can only build and run, or <em>not</em> build and run, successfully under macOS (or Windows). Remember that I can use logical operators like <code>!</code> (not) with my compilation conditions.</p>
<p>I generally use <code>DEBUG</code> to report on and sometimes act upon error conditions. I generally use <code>LOG</code> when my code needs an audit trail (like when processing sensitive data).</p>
<p>If, for example, I have to deal with core code specific to Mac, and debugging and logging, I would use the following generalized though runnable <code>ViewController.swift</code> file:</p>
<pre class="swift">class ViewController: UIViewController {
    
    var loginAttempts: Int = 0
    
    @IBAction func loginButtonPressed(_ sender: Any) {
        
#if LOG
        print(&quot;Login button pressed&quot;)
        loginAttempts += 1
        if loginAttempts &gt; 3 {
            print(&quot;HACK ATTEMPTED?&quot;)
            // CALL 911!
        }
#endif

    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
#if WIN
        print(&quot;Use Windows code...&quot;)
#elseif MAC
        print(&quot;Use Mac code...&quot;)
#endif
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
        
#if DEBUG
        print(&quot;ViewController::didReceiveMemoryWarning&quot;)
#endif
    }

} // end class ViewController
</pre>
<p>Let&#x2019;s say I build and distribute my app using the &#x201C;Xcode Targets &#x2013; Release&#x201D; target. Here&#x2019;s the console output from the previous code snippet:</p>
<pre class="swift">Use Mac code...
Login button pressed
Login button pressed
Login button pressed
Login button pressed
HACK ATTEMPTED?
</pre>
<p>The main takeaway here is that you can define as many or as few compilation conditions as you like and specify differing combinations of those conditions in different targets. While I generally frown upon conditionally compiling code, there are times when nothing else works in complex, realworld scenarios. I&#x2019;m more comfortable with using compilation conditions for situations like turning logging (i.e. <code>print</code> statements) off and on.</p>
<h2>Different app flavors/branding</h2>
<p>What if you&#x2019;ve licensed your code to partners/resellers who want their own branding, like custom logos/icons and specific product names, to be displayed by an app? In the iOS App Store, Apple generally frowns on a bunch of identical apps that only differ in their main icons&#x2026; at least they said they do ;-). But you definitely can have multiple versions of the same app(s) differing in the sense of up-selling from free to intermediate to advanced features and functionality. Branding or &#x201C;flavors&#x201D; of iOS apps is much more flexible in an Apple Developer Enterprise Program environment. In macOS development, Apple allows you to build, brand, and distribute apps without going through the Mac App Store, and thus you&#x2019;re afforded much more flexibility.</p>
<p>Do differing icons, graphics, text, and tiered features warrant multiple Xcode projects? Generally, no. Why don&#x2019;t we just use targets? I&#x2019;ve supported apps that have 10 different flavors.</p>
<p>To show you how you can leverage targets to handle branding, I created an Xcode project for macOS, based on the <em>Cocoa App</em> template, and named it &#x201C;Xcode Manage Config.&#x201D; You can download it from <a href="https://github.com/appcoda/Xcode-Targets/tree/master/Xcode%20Manage%20Config?ref=appcoda.com">GitHub</a>.</p>
<p>My project shows you how you can abstract out and customize an app&#x2019;s:</p>
<ol>
<li>Help bundle</li>
<li>Name</li>
<li>Version number</li>
<li>Icon</li>
<li>Copyright text</li>
</ol>
<p>All are done without hacking (i.e. without using if statements and hardcoding values). Reviewing the code and commentary in my sample project&#x2019;s <code>ViewController.swift</code> file should give you a good idea of how I abstracted all details for the 5 tasks I just listed out of code and into targets:</p>
<pre class="swift">import Cocoa

let reverseDomain = &quot;us.microit.&quot;

class ViewController: NSViewController {
    
    @IBOutlet weak var logoImage: NSImageView!
    @IBOutlet weak var productName: NSTextField!
    @IBOutlet weak var copyright: NSTextField!
    @IBOutlet weak var version: NSTextField!
    
    var helpPath: String = &quot;&quot;
    
    override func viewDidLoad() {
        
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        // Get the product name by stripping out the
        // reverse domain name.
        let bundleIdentifier = Bundle.main.bundleIdentifier?.replacingOccurrences(of: reverseDomain, with: &quot;&quot;)
        
        // Display the product name.
        productName.stringValue = bundleIdentifier!
        
        // Build app icon set name using concatenation.
        let appIconSetName:String = bundleIdentifier! + &quot;AppIcon&quot;
        // Get and display the product logo.
        logoImage.image = NSImage(named: NSImage.Name(rawValue: appIconSetName))
        
        // Get the copyright statement.
        let copyrightString = Bundle.main.object(forInfoDictionaryKey: &quot;NSHumanReadableCopyright&quot;)
        // Display the product copyright.
        copyright.stringValue = copyrightString! as! String
        
        // Get the product version.
        let versionString = Bundle.main.object(forInfoDictionaryKey: &quot;CFBundleShortVersionString&quot;)
        // Display the version.
        version.stringValue = &quot;Version: &quot; + (versionString! as! String)
        
        // Build and save the path to help files.
        helpPath = Bundle.main.path(forResource: &quot;index&quot;, ofType: &quot;html&quot;, inDirectory: bundleIdentifier!)!
        
    } // end func viewDidLoad()
    
    @IBAction func invokeHelp(_ sender: Any) {
        // Open help in default browser.
        NSWorkspace.shared.openFile(helpPath)
    }
    
    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

} // end class ViewController
</pre>
<p>Let&#x2019;s build and run the code to see how targets can differentiate two licensors of the same software but with different branding. Let&#x2019;s build and run the &#x201C;Acme &#x2013; Release&#x201D; target:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14239" src="https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme-1024x648.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="648" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme-1024x648.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme-200x127.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme-474x300.png 474w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme-768x486.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme-860x544.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme-680x430.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme-400x253.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme-50x32.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutAcme.png 1166w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Now let&#x2019;s build and run the &#x201C;Emca &#x2013; Release&#x201D; target:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14240" src="https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca-1024x652.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="652" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca-1024x652.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca-200x127.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca-471x300.png 471w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca-768x489.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca-860x548.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca-680x433.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca-400x255.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca-50x32.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/AboutEmca.png 1162w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Notice that nothing was hardcoded&#x2026; well, except my reverse domain name, and that <strong>hasn&#x2019;t been changed since 1999</strong>. It could easily be abstracted into a <code>plist</code>. Please forgive my one, minor transgression. Notice that the official app icons for each target are recognized by macOS:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14243" src="https://www.appcoda.com/content/images/wordpress/2018/10/AppIconsDock.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="250" height="94" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/AppIconsDock.png 250w, https://www.appcoda.com/content/images/wordpress/2018/10/AppIconsDock-200x75.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/AppIconsDock-50x19.png 50w" sizes="(max-width: 250px) 100vw, 250px"></p>
<p>What if we click on the &#x201C;Help&#x201D; button in either target&#x2019;s app? This is help customized to the &#x201C;Acme &#x2013; Release&#x201D; target, running in Safari:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14241" src="https://www.appcoda.com/content/images/wordpress/2018/10/AcmeHelp.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1020" height="716" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/AcmeHelp.png 1020w, https://www.appcoda.com/content/images/wordpress/2018/10/AcmeHelp-200x140.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/AcmeHelp-427x300.png 427w, https://www.appcoda.com/content/images/wordpress/2018/10/AcmeHelp-768x539.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/AcmeHelp-860x604.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/AcmeHelp-680x477.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/AcmeHelp-400x281.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/AcmeHelp-50x35.png 50w" sizes="(max-width: 1020px) 100vw, 1020px"></p>
<p>The &#x201C;Emca &#x2013; Release&#x201D; target&#x2019;s help is differentiated:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14249" src="https://www.appcoda.com/content/images/wordpress/2018/10/EmcaHelp.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1018" height="770" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/EmcaHelp.png 1018w, https://www.appcoda.com/content/images/wordpress/2018/10/EmcaHelp-200x151.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/EmcaHelp-397x300.png 397w, https://www.appcoda.com/content/images/wordpress/2018/10/EmcaHelp-768x581.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/EmcaHelp-860x650.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/EmcaHelp-680x514.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/EmcaHelp-400x303.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/EmcaHelp-50x38.png 50w" sizes="(max-width: 1018px) 100vw, 1018px"></p>
<p><strong><em>The help bundle</em></strong><br>
A help bundle is often just a directory containing <code>HTML</code> files/resources. I dragged help folders named &#x201C;Emca&#x201D; and &#x201C;Acme&#x201D; into the <em>Project Navigator</em>. I was prompted by Xcode both times. I&#x2019;ll just show you the prompt for the &#x201C;Acme&#x201D; folder. Notice I <em>only</em> set the &#x201C;Acme&#x201D; folder to be a member of the &#x201C;Acme &#x2013; Release&#x201D; target:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14242" src="https://www.appcoda.com/content/images/wordpress/2018/10/AddAcmeHelp.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="731" height="430" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/AddAcmeHelp.png 731w, https://www.appcoda.com/content/images/wordpress/2018/10/AddAcmeHelp-200x118.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/AddAcmeHelp-510x300.png 510w, https://www.appcoda.com/content/images/wordpress/2018/10/AddAcmeHelp-680x400.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/AddAcmeHelp-400x235.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/AddAcmeHelp-50x29.png 50w" sizes="(max-width: 731px) 100vw, 731px"></p>
<p>If you click on the &#x201C;Emca&#x201D; folder in Xcode&#x2019;s <em>Project Navigator</em>, you&#x2019;ll see its <em>Target Membership</em> is <strong>only</strong> ticked for the &#x201C;Emca &#x2013; Release&#x201D; target:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14250" src="https://www.appcoda.com/content/images/wordpress/2018/10/EmcaTargetMember.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="288" height="136" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/EmcaTargetMember.png 288w, https://www.appcoda.com/content/images/wordpress/2018/10/EmcaTargetMember-200x94.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/EmcaTargetMember-50x24.png 50w" sizes="(max-width: 288px) 100vw, 288px"></p>
<p>I&#x2019;ve seen multi-megabyte help bundles, so if you insist on including the actual help resources in your project, make sure you&#x2019;re not including stuff that you don&#x2019;t need, like don&#x2019;t include Acme&#x2019;s help in Emca and vice versa. On a side note, believe it or not, I&#x2019;ve heard <em>many</em> customers insist that they get the actual help included in-situ in their products.</p>
<p>If you plan building, signing, and creating a signed installer for one or both of the &#x201C;Xcode Manage Config&#x201D; project&#x2019;s targets, you need to take a few extra steps. For one thing, remember to go to <em>Build Phases</em> -&gt; <em>Copy Bundle Resources</em> and add the &#x201C;Acme&#x201D; folder for copying in the &#x201C;Acme &#x2013; Release&#x201D; target, and similarly add the &#x201C;Emca&#x201D; folder for copying in the &#x201C;Emca &#x2013; Release&#x201D; target. Again, two products; two different targets.</p>
<p><strong><em>The app name and version number</em></strong><br>
The app name and version number are distinct per target. You set them by selecting the target and then going to <em>General</em> -&gt; <em>Identity</em>. I&#x2019;ll just show you how I set the values for the &#x201C;Emca &#x2013; Release&#x201D; target:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14265" src="https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer-1024x414.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="414" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer-1024x414.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer-200x81.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer-600x243.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer-768x311.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer-860x348.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer-680x275.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer-400x162.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer-50x20.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/SetAppNameVer.png 1132w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p><strong><em>The app icon</em></strong><br>
Here, you can see that I&#x2019;ve already set the app icon for &#x201C;Acme &#x2013; Release&#x201D; and am about to create a new app icon set for &#x201C;Emca &#x2013; Release&#x201D; &#x2014; this is in the <em>Asset Catalog</em> which is shared by all targets:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14255" src="https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-1024x837.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="837" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-1024x837.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-200x163.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-367x300.png 367w, https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-768x628.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-1240x1013.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-860x703.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-680x556.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-400x327.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon-50x41.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/NewAppIcon.png 1334w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Notice that in my code above, I get the code-independent <em>Bundle Identifier</em> and append &#x201C;AppIcon&#x201D; to it to get the app icon set appropriate to the current target.</p>
<p><strong><em>The copyright text</em></strong><br>
I arranged the <code>Info.plist</code> files for the two targets in this project as I had discussed above in the first sample project. As you&#x2019;d expect, there&#x2019;s an <code>Info-Acme.plist</code> for the &#x201C;Acme &#x2013; Release&#x201D; target and an <code>Info-Emca.plist</code> for the &#x201C;Emca &#x2013; Release&#x201D; target. Changing the copyright text is code independent. You highlight the <code>plist</code> file in each target, click into the <code>Copyright (human-readable)</code> string value, and make your edits like so:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14248" src="https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-1024x476.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="476" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-1024x476.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-200x93.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-600x279.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-768x357.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-1240x577.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-860x400.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-680x316.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-400x186.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR-50x23.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/EditingPlistCR.png 1342w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>We just went through a whole slew of examples of how you can leverage targets for keeping your app code and resources centralized <em>and</em> giving you the flexibility to make changes, like generating multiple flavors of the same app, <em>without</em> using hacks like hardcoding, writing scripts, or writing pyramid-of-doom <code>if</code> statements.</p>
<h2>Different dependencies for different app platforms</h2>
<p>Over the years, I&#x2019;ve designed, encoded, used, and accumulated a lot of good, solid C++ code. This code is meant for solving a wide range of problems, or modelling a major gamut of everyday scenarios, for example, messaging, statistical tests, data manipulation, etc. Over the years, I&#x2019;ve learned to <em>first</em> look for <em>existing</em> code that I can reuse <em>before</em> spending hundreds of hours reinventing the wheel&#x2026; again (and again).</p>
<div class="alert gray"><strong>Tip:</strong> Remember that you can divide and conquer your Swift code too by breaking it into modules like frameworks.</div>
<p>What does this have to do with targets? I&#x2019;m going to show you how you can reuse existing code in one Xcode project that has targets for macOS and iOS (and tvOS and watchOS if you put a little thought into it). So one project can allow you to build binaries and reuse them in four different Apple app types.</p>
<p>I could show you how to do this <a href="http://iosbrain.com/blog/2018/01/13/building-swift-4-frameworks-and-including-them-in-your-apps-xcode-9/?ref=appcoda.com">with frameworks</a>, and that&#x2019;s the direction to which you&#x2019;ll want to head, but to keep this didactic, short, and simple, I&#x2019;m just going to build libraries. You can download a library-based project I created named &#x201C;Xcode Cocoa Library&#x201D; from <a href="https://github.com/appcoda/Xcode-Targets/tree/master/Xcode%20Cocoa%20Library?ref=appcoda.com">GitHub</a> if you want to follow along.</p>
<p>Create a new Xcode project using these settings:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14257" src="https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-1024x741.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="741" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-1024x741.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-200x145.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-415x300.png 415w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-768x556.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-1240x897.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-860x622.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-680x492.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-400x289.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary-50x36.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrary.png 1468w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Click <em>Next</em> and configure thusly:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14258" src="https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-1024x740.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="740" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-1024x740.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-200x145.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-415x300.png 415w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-768x555.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-1240x896.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-860x622.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-680x492.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-400x289.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings-50x36.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/NewPortableLibrarySettings.png 1472w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Click <em>Next</em> and save in a location of your choosing. In the <em>Project Navigator</em>, find the file <code>Xcode_Cocoa_Library.m</code> and rename it to <code>Xcode_Cocoa_Library.mm</code> to be sure that C++ and Objective-C++ are supported.</p>
<p>As we did earlier, <em>Duplicate</em> the &#x201C;Xcode Cocoa Library&#x201D; target, renaming the new target and associated scheme as &#x201C;Xcode iOS Library.&#x201D; At this point, your project should look like so:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14252" src="https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged-1024x414.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="414" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged-1024x414.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged-200x81.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged-600x242.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged-768x310.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged-860x348.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged-680x275.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged-400x162.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged-50x20.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/InitLibConfiged.png 1064w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Highlight the &#x201C;Xcode Cocoa Library&#x201D; target, go to <em>Build Settings</em>, and look at the <em>Architectures</em> section. You&#x2019;ll note that the library is configured to be run under macOS on an Intel-based machine:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14254" src="https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch-1024x467.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="467" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch-1024x467.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch-200x91.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch-600x274.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch-768x350.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch-860x392.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch-680x310.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch-400x182.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch-50x23.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/MacOSArch.png 1210w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>Notice the target builds successfully.</p>
<p>Highlight the &#x201C;Xcode iOS Library&#x201D; target, go to <em>Build Settings</em>, and look at the <em>Architectures</em> section. Change the <em>Base SDK</em> to the latest version of iOS, like so:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14244" src="https://www.appcoda.com/content/images/wordpress/2018/10/ChangePlatformToiOS.gif" alt="Dividing and Conquering Your Xcode Projects with Targets" width="864" height="290"></p>
<p>You should notice that the library is configured to be run under iOS on an ARM-based machine. Build the &#x201C;Xcode iOS Library&#x201D; target. Notice the target builds successfully.</p>
<p>Let&#x2019;s add some code to the project just to be sure we can write C++ and Objective-C++. (Note that many times I&#x2019;ve added rock-solid existing C++ .h and .cpp files, blended in some Objective-C and Objective-C++, and <strong>was able to reuse mountains of code in my macOS, watchOS, and iOS apps.</strong>)</p>
<p>Here&#x2019;s file <code>Xcode_Cocoa_Library.h</code>:</p>
<pre class="swift">#import &lt;Foundation/Foundation.h&gt;
#include &lt;iostream&gt;

@interface Xcode_Cocoa_Library : NSObject

- (void)helloWorld;

@end

class Parent {
public:
    virtual void soundOff() {
        std::cout &lt;&lt; &quot;This is the parent class&quot; &lt;&lt; std::endl;
    }
};

class Child: public Parent {
public:
    virtual void soundOff() {
        std::cout &lt;&lt; &quot;This is the child class&quot; &lt;&lt; std::endl;
    }
};
</pre>
<p>Here&#x2019;s file <code>Xcode_Cocoa_Library.mm</code>:</p>
<pre class="swift">#import &quot;Xcode_Cocoa_Library.h&quot;

@implementation Xcode_Cocoa_Library

- (void)helloWorld {
    
    Child child;
    child.soundOff();
    
    NSLog(@&quot;Hello, world!&quot;);
    
}

@end
</pre>
<p>Build both targets with the new code added. Here&#x2019;s the result (success):</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14253" src="https://www.appcoda.com/content/images/wordpress/2018/10/LibsBuildSuccess.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="474" height="302" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/LibsBuildSuccess.png 474w, https://www.appcoda.com/content/images/wordpress/2018/10/LibsBuildSuccess-200x127.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/LibsBuildSuccess-471x300.png 471w, https://www.appcoda.com/content/images/wordpress/2018/10/LibsBuildSuccess-400x255.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/LibsBuildSuccess-50x32.png 50w" sizes="(max-width: 474px) 100vw, 474px"></p>
<p>These library names would be red if they failed to build.</p>
<p>I&#x2019;m not going to show you how to consume this library in a Swift-based project, as it&#x2019;s beyond the scope of this tutorial. Rest assured that I&#x2019;ve incorporated such libraries (and static libs and frameworks) many times into Swift-based projects (generally using a wrapper, a bridging header, and of course, including the libraries&#x2019; header files).</p>
<p>The point I&#x2019;m making here is that you can reuse code and organize it, without using hacks, build for multiple platforms, and get great maintainability and extensibility. How? By using targets.</p>
<h2>Truly universal app code</h2>
<p>Take a look at this image from the &#x201C;Xcode Cocoa Library&#x201D; project discussed in the last section:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-14267" src="https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-1024x439.png" alt="Dividing and Conquering Your Xcode Projects with Targets" width="1024" height="439" srcset="https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-1024x439.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-200x86.png 200w, https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-600x257.png 600w, https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-768x329.png 768w, https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-1240x532.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-860x369.png 860w, https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-680x292.png 680w, https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-400x172.png 400w, https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture-50x21.png 50w, https://www.appcoda.com/content/images/wordpress/2018/10/TowardsFuture.png 1268w" sizes="(max-width: 1024px) 100vw, 1024px"></p>
<p>I could create two new targets, one for tvOS and one for watchOS. If I organize code properly, keeping abstraction in mind, I can build, maintain, and extend functionality for macOS, iOS, tvOS, and watchOS <strong>all in one project.</strong></p>
<h2>Conclusion</h2>
<p>In reality, I currently have libraries that allow me to reuse much of my over-the-years-accumulated C, C++, Objective-C, Objective-C++, and Swift code in macOS, iOS, tvOS, and watchOS apps. The reason I mention all these languages is that Xcode&#x2019;s targets and schemes have enabled me to reuse a lot of code I&#x2019;ve written in the past &#x2014; <em>and</em> I&#x2019;ve been able to reuse my legacy code on <em>multiple</em> Apple platforms, namely iOS, macOS, watchOS, and a bit of tvOS.</p>
<p>I&#x2019;ve <em>only</em> been able to do that by planning, doing requirements analysis, designing first before coding, concentrating on abstraction &#x2014; looking before leaping. I&#x2019;ve been able to abstract so much code by <em>implementing</em> concepts and techniques like <a href="https://www.appcoda.com/swift-class-best-practice/">best practices for building classes</a>, <a href="https://www.appcoda.com/mvvm-vs-mvc/">using architectural design patterns like MVVM</a>, using tactical design patterns (<a href="https://www.appcoda.com/design-pattern-creational/">here</a>, <a href="https://www.appcoda.com/design-pattern-behavorial/">here</a>, and <a href="https://www.appcoda.com/design-pattern-structural/">here</a>), and, of course, using <a href="https://www.appcoda.com/pop-vs-oop/">object-oriented and protocol-oriented programming</a> techniques.</p>
<p>I&#x2019;m waxing theoretical. You&#x2019;ve got <strong>great tools</strong> available to you, like Xcode and its targets and schemes. Don&#x2019;t be a just-get-it-done developer. Invest some time into reading up on the documentation provided with Xcode. Look at some third party books and videos. Join special interest groups and social media groups. Take the information you glean from your studying and <strong>put it to practice</strong> in your everyday work. Don&#x2019;t be a stick in the mud. <strong>Try new things and constantly push the envelope.</strong></p>
<p>If you take the time, you&#x2019;ll find that tools like Xcode provide features beyond your wildest dreams.</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Best Practices for Building Swift Classes]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>In this tutorial, I&#x2019;m going to give you some best practices that will help you safely and effectively use classes (reference types) and reference semantics in Swift. Protocol-oriented programming (POP) and value semantics are all the rage now, but a promising new technology doesn&#x2019;t mean you</p>]]></description><link>https://www.appcoda.com/swift-class-best-practice/</link><guid isPermaLink="false">66612a0f166d3c03cf01147f</guid><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Fri, 28 Sep 2018 17:10:06 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2018/09/dmitry-mashkin-973344-unsplash.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->
<img src="https://www.appcoda.com/content/images/wordpress/2018/09/dmitry-mashkin-973344-unsplash.jpg" alt="Best Practices for Building Swift Classes"><p>In this tutorial, I&#x2019;m going to give you some best practices that will help you safely and effectively use classes (reference types) and reference semantics in Swift. Protocol-oriented programming (POP) and value semantics are all the rage now, but a promising new technology doesn&#x2019;t mean you should throw all your classes away. Why not add some simple constructs to your classes like copy initializers, default initializers, designated initializers, deinitializers, and conformance to the <code>Equatable</code> protocol? To get real about my sample code, I&#x2019;ll adopt these constructs in some classes that you can use for drawing in your iOS app interfaces.</p>
<p>I&#x2019;ll walk through the process of creating several protocols, creating classes that adopt those protocols, implement inheritance in these classes, and use instances of the classes (objects), all to illustrate my best practices &#x2014; and to show some of the extra steps you may have to go through when working with classes.</p>
<h2>Using Protocols as much as possible</h2>
<p>Defining and using protocols makes your intent crystal clear when defining new classes. When you and other developers look at the signature for your classes, you get meaningful information immediately (like &#x201C;this class supports a copy constructor&#x201D;). I also like to confine the requirements of my protocols to one purpose. Since I break my protocols up into focused sets of requirements, my classes can adopt as many or as few protocols as required.</p>
<h2>POP, OOP, and POOP?</h2>
<p>Remember one very important point: Most code in the iOS (and OS X) SDKs comes in the form of class hierarchies. I believe many of the core frameworks we use <a href="https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Cocoa.html?ref=appcoda.com">are still written in Objective-C (and some C++ and C)</a>, like <code>Foundation</code> and <code>UIKit</code>.</p>
<p>Think about creating a new Xcode project based on the iOS <code>Single View App</code> template. Where do many developers get started in this new type of project? Right, in file <code>ViewController.swift</code>. And what do we all see when opening that file? We see  <code>ViewController</code> which is a <em>subclass</em> of <code>UIViewController</code>.</p>
<p>What does Apple have to say about <code>ViewController</code>? Here <a href="https://developer.apple.com/documentation/uikit/uiviewcontroller?ref=appcoda.com">we go</a>:</p>
<blockquote><p>
  &#x2026;You rarely create instances of the <code>UIViewController</code> class directly. Instead, you subclass <code>UIViewController</code> and add the methods and properties needed to manage the view controller&#x2019;s view hierarchy. &#x2026;</p>
<p>  Every app contains at least one custom subclass of <code>UIViewController</code>. More often, apps contain many custom view controllers. Custom view controllers define the overall behaviors of your app, including the app&#x2019;s appearance and how it responds to user interactions.
</p></blockquote>
<p>Yeah, yeah, yeah&#x2026; Apple is pushing protocol-oriented programming (POP), value types (structs and enums), and value semantics. Got it. Heard it loud and clear. But classes (reference types), with their reference semantics and object-oriented programming (OOP) capabilities, will be around for awhile.</p>
<p>There&#x2019;s always some new programming fad. The only thing I&#x2019;m concerned about is whether POP is <em>really</em> useful or just another marketing ploy. So far, it has proven useful in my production code, but <em>not all of the time</em>.</p>
<h2>The Thing about Classes</h2>
<p>Reference types (classes) and reference semantics can be boon or bane, depending on how you use them. But that&#x2019;s true of all prominently-used technologies. There are advantages <em>and</em> disadvantages. To paraphrase Shakespeare, &#x201C;To copy or not to copy: that is the question.&#x201D; My answer to the question is to first understand the problem at hand, trust my intuition, and use copying &#x2014; value semantics &#x2014; when necessary, and to not use copying &#x2014; reference semantics &#x2014; when necessary.</p>
<p>Even with Apple&#x2019;s supposed move towards POP, one of the Apple engineers at WWDC 2015 pointed out that <a href="https://developer.apple.com/videos/play/wwdc2015-408/?time=2566&amp;ref=appcoda.com">&#x201C;So, for example, a Window. What would it mean to copy a Window?&#x201D;</a> It wouldn&#x2019;t mean anything except confusion. Indeed, what would a <em>copy</em> of a <code>UIViewController</code> subclass instance mean and what would you do with it? Entities like <code>UIViewController</code> and <code>NSWindow</code> should remain as classes.</p>
<p>Suppose you used the <a href="https://www.appcoda.com/design-pattern-structural/">facade design pattern</a> to create a simple interface and wrapper for a very complex database system that must be used by all customers who&#x2019;ve bought your app. The most straightforward way to sensibly use this database would be to pass a <em>reference</em> to it around your app. Why in G-d&#x2019;s name would you write a value type (struct) version of this database and give a <em>copy</em> of the database infrastructure and all its data to each instance of your app? You&#x2019;d have a disaster.</p>
<p>Obviously, classes still have a place in the software development world. And <em>please</em> don&#x2019;t think that making a class a member property of a struct is the answer to your prayers. That member property will exhibit reference semantics.</p>
<h3>The problem with classes</h3>
<p>You all probably know what I&#x2019;m going to talk about. Here it is from an <a href="https://developer.apple.com/swift/blog/?id=10&amp;ref=appcoda.com">old Swift blog post</a>:</p>
<blockquote><p>
Copying a reference&#x2026; implicitly creates a shared instance. After a copy, two variables then refer to a single instance of the data, so modifying data in the second variable also affects the original.&#x201D;
</p></blockquote>
<p>Here&#x2019;s an example of the potential perils of reference semantics: I&#x2019;ll create a class instance, then declare a reference it, then declare another reference to it, set the latter reference equal to the former reference, end up with two references to the same object/instance, change a member property on the latter reference, and see that change reflected in the one instance:</p>
<pre>
class Coordinate
{
    var x: Float
    var y: Float
    
    init( x: Float, y: Float ) {
        self.x = x
        self.y = y
    }
}

var coordinate = Coordinate(x: 2.0, y: 4.0)
print(&quot;coordinate:  (\(coordinate.x), \(coordinate.y))&quot;)
// coordinate:  (2.0, 4.0)

// Unintended mutation?
var coordinate1 = coordinate
coordinate1.y = 0.0

print(&quot;coordinate:  (\(coordinate.x), \(coordinate.y))&quot;)
// coordinate:  (2.0, 0.0)

print(&quot;coordinate1: (\(coordinate1.x), \(coordinate1.y))&quot;)
// coordinate1: (2.0, 0.0)

coordinate === coordinate1
// true
</pre>
<p>Output to console from the previous code snippet:</p>
<pre>
coordinate:  (2.0, 4.0)
coordinate:  (2.0, 0.0)
coordinate1: (2.0, 0.0)
</pre>
<p>Since objects <code>coordinate</code> and <code>coordinate1</code> both are <em>references</em> to the object created by the statement <code>Coordinate(x: 2.0, y: 4.0)</code>, changes to either reference changes both objects. The statement <code>var coordinate1 = coordinate</code> is an example of <em>copying</em> a reference.</p>
<p>Note my use of the logical <code>===</code> operator:</p>
<pre>
coordinate === coordinate1
// true
</pre>
<p>From the <a href="https://swiftdoc.org/v4.2/operator/eqeqeq/?ref=appcoda.com">Swift docs</a>, <code>===</code> &#x201C;Returns a Boolean value indicating whether two references point to the same object instance.&#x201D; Obviously, in this case, <code>coordinate</code> and <code>coordinate1</code> refer to the <em>same</em> instance. Remember that <a href="https://developer.apple.com/documentation/swift/equatable?ref=appcoda.com">&#x201C;Equality is Separate From Identity&#x201D;</a> and <a href="https://developer.apple.com/documentation/swift/equatable?ref=appcoda.com">&#x201C;The identity of a class instance is not part of an instance&#x2019;s value.&#x201D;</a></p>
<p>In even the smallest of apps, I&#x2019;ve seen errors occur because of <a href="https://developer.apple.com/videos/play/wwdc2015-414/?time=112&amp;ref=appcoda.com">&#x201C;unintended sharing,&#x201D;</a> unintended mutation &#x2014; whatever you want to call creating multiple references to the same object and changing a property in one of those references. This behavior can be especially difficult to debug in multi-threaded code involving reference types. But guess what? You can write bad code using value types.</p>
<p>Changes to the first instance of some struct and subsequent changes to copies could still be &#x201C;unintended.&#x201D; Any what if you end up with a bunch of copies of a struct? Is it semantically clear as to what your code is doing? Even Apple <a href="https://developer.apple.com/videos/play/wwdc2015/414/?time=369&amp;ref=appcoda.com">admits it</a>: &#x201C;The problem is that immutability has some disadvantages.&#x201D;</p>
<p>We can get into a discussion of making our classes safe by using Apple&#x2019;s version of <a href="https://developer.apple.com/videos/play/wwdc2015-414/?time=210&amp;ref=appcoda.com">&#x201C;defensive copying.&#x201D;</a> where we make all our classes adopt the <code>NSCopying</code> (and perhaps <code>NSObject</code>) protocol(s), and then make sure all our classes implement <a href="https://developer.apple.com/documentation/foundation/nscopying/1410311-copy?ref=appcoda.com"><code>copy(with:)</code></a> (mainly just <code>copy()</code>), and <em>remember to call</em> <code>copy()</code> constantly, on every assignment. And calling <code>copy()</code>  requires a cast:</p>
<pre class="swift">
let objectCopy = object.copy() as! ObjectType
</pre>
<p>Be aware that defensive copying is all over Cocoa and Objective-C. There are still many developers who have to support entire legacy iOS and OS X codebases. And there are many of us who must interact with legacy iOS and OS X codebases. We&#x2019;re not going to take the <code>NSCopying</code> tack in this tutorial. While I will show you some code for defensive copying, I will also show you many other techniques to make your use of classes safe.</p>
<h2>Getting Started with a Playground</h2>
<p>Let&#x2019;s create a new Xcode playground. In Xcode, go to <em>File</em> -&gt; <em>New &gt;</em> -&gt; <em>Playground&#x2026;</em> and click <em>iOS</em> and the <em>Single View</em> template icon. Click the <em>Next</em> button, select a location for your new playground&#x2019;s bundle, give your playground a name, and click the <em>Create</em> button. Or you can download my sample Xcode playground from <a href="https://github.com/appcoda/Swift-Class-Best-Practices?ref=appcoda.com">GitHub</a>.</p>
<p>Make some room in your playground where my comment &#x201C;PUT SOME SPACES HERE&#x201D; is located (shown below) for the class-based code I&#x2019;m going to write during this tutorial, like so:</p>
<pre>
//: A UIKit based Playground for presenting user interface
  
import UIKit
import PlaygroundSupport

//
// PUT SOME SPACES HERE
//

class MyViewController : UIViewController {
...
</pre>
<p>Now replace the &#x201C;PUT SOME SPACES HERE&#x201D; comments with the protocol named <code>Copyable</code> and class called <code>Line</code>, as shown below:</p>
<pre>
//: A UIKit based Playground for presenting user interface
  
import UIKit
import PlaygroundSupport

protocol Copyable: class {
    
    func copy() -&gt; Self
    
}

class Line {
    
    var beginPoint: CGPoint
    var endPoint: CGPoint
    
    init( beginPoint: CGPoint, endPoint: CGPoint ) {
        
        self.beginPoint = CGPoint( x: beginPoint.x, y: beginPoint.y )
        self.endPoint = CGPoint( x: endPoint.x, y: endPoint.y )
        
    }
    
} // end class Line

class MyViewController : UIViewController {
...
</pre>
<p>You should be able to tell that objects of this class can be used to represent geometric, straight lines by defining beginning points and endpoints. I&#x2019;ve used the <code>CGPoint</code> class to represent my beginning points and endpoints so that this class is very compatible with drawing/graphics. Currently, the <code>Line</code> class only has a <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html?ref=appcoda.com#ID217">designated initializer</a>.</p>
<h2>Best Practices for Classes</h2>
<p>Based on the evidence I&#x2019;ve seen from the evolution of the Swift language, my own experiences with Swift, and observing the experiences of others developing with Swift, classes aren&#x2019;t going away. OOP features, made possible by use of classes, like inheritance, virtual methods, and polymorphism aren&#x2019;t going away because they&#x2019;re just too darn useful.</p>
<p>Let me show you some techniques I use to mitigate &#x201C;unintended sharing&#x201D; in classes &#x2014; and also other approaches you can use just to write better and semantically clear class-based code. A lot of what I&#x2019;m sharing with you here comes from my years of experience writing <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines?ref=appcoda.com">C++ code</a>.</p>
<h3>Copy constructor (copy initializer)</h3>
<p>You may have noticed the <code>Copyable</code> protocol in the initial code I added to our playground. Unintended mutation is one of the biggest critiques of reference semantics, so we&#x2019;re going to start by mitigating class mutation. Notice my use of <code>Self</code> with a capitalized &#x201C;S&#x201D; as opposed to <code>self</code> with a lowercase &#x201C;s&#x201D; in my <code>Copyable</code> protocol. This is no accident. From the <a href="https://docs.swift.org/swift-book/ReferenceManual/Declarations.html?ref=appcoda.com#ID374">Swift docs</a>: &#x201C;Self refers to the eventual type that conforms to the protocol.&#x201D; If you&#x2019;re unclear as to what differentiates <code>Self</code> from <code>self</code>, I suggest you <a href="http://iosbrain.com/blog/2018/09/26/self-versus-self-in-swift-4-capital-s-and-lowercase-s/?ref=appcoda.com">study up on the subject</a>.</p>
<p>Why not recognize the &#x201C;problem&#x201D; of &#x201C;unintended sharing&#x201D; outright and make a semantic statement about it with a protocol that will require conforming classes to implement a &#x201C;copy constructor?&#x201D; To climb out of my C++ past, I&#x2019;ll use Swift terminology and say &#x201C;copy initializer.&#x201D; A copy initializer allows us to create an instance of a class using another instance of a class. A new object is created containing the same member properties as another object of the same type. Let me be clear: A fully independent <em>copy</em> of an object is made. Though the new object contains the same data as the original, a new <em>instance</em> (object) is created. The new object <em>is not</em> a reference to the original object. It is a <em>copy</em> and the semantics of the copy initializer makes your intent clear.</p>
<p>Making a copy of a class instance can give you a form of immutability &#x2014; a baseline to which you can compare future changes to that instance, and/or a way to restore the instance&#x2019;s state if something goes wrong later.</p>
<p>Notice that Swift almost seems to frown on making a <em>copy</em> of a reference type, i.e., a <em>copy</em> of an instance of a class, or, as some would rather put it, getting a copy of an object. I&#x2019;m not talking about getting another <em>reference</em> to a class, I&#x2019;m talking about getting an <em>entire</em>, <em>separate</em> copy of a class instance. This frowning on class copying is not an accident. Swift&#x2019;s language architects want the syntax and semantics of the language to be crystal clear. They want developers to be confident that reference types and value types will both have <strong>1)</strong> distinct and obvious meanings and that both types will <strong>2)</strong> behave consistently. But still, why not be able to safely make a copy of a class instance? I&#x2019;ll show you how in this tutorial by borrowing the <em>copy constructor</em> concept from C++. In Swift, we&#x2019;d call this a <a href="http://iosbrain.com/blog/2018/09/23/class-copy-constructors-in-swift-4-for-defensive-copying/?ref=appcoda.com">&#x201C;copy initializer.&#x201D;</a></p>
<p>Swift is <a href="https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html?ref=appcoda.com#ID44">downright difficult about allowing copying of class instances</a>:</p>
<blockquote><p>
  It is not possible to overload the default assignment operator (<code>=</code>).
</p></blockquote>
<p>In C++, I would override the assignment operator to allow my class to make deep copies of its instances (i.e., their properties&#x2019; <em>values</em>) and thus help prevent unwanted changes. I&#x2019;d also create a copy constructor. I can even <a href="https://www.learncpp.com/cpp-tutorial/9-14-overloading-the-assignment-operator/?ref=appcoda.com">turn off assignment</a> in C++ by making my assignment operator private. Swift isn&#x2019;t C++, but does support one of the ideas I&#x2019;ve floated, but only if you build a <em>custom</em> version.</p>
<p>Let&#x2019;s make my <code>Line</code> class adopt my <code>Copyable</code> protocol. <code>Copyable</code> requires a conforming class to implement a copy initializer:</p>
<pre class="swift">
protocol Copyable: class {
    
    func copy() -&gt; Self
    
}

class Line : Copyable {

    var beginPoint: CGPoint
    var endPoint: CGPoint
    
    init( beginPoint: CGPoint, endPoint: CGPoint ) {
        
        self.beginPoint = CGPoint( x: beginPoint.x, y: beginPoint.y )
        self.endPoint = CGPoint( x: endPoint.x, y: endPoint.y )
        
    }
    
    func copy() -&gt; Self {
        
        return type(of: self).init( beginPoint: self.beginPoint,
                                    endPoint: self.endPoint )

    }

} // end class Line
</pre>
<p>I want <code>copy()</code> to instantiate a new instance of my <code>Line</code> class with its current member property values and return that instance. It will do that, but only until I clear up the &#x201C;Constructing an object of class type &#x2018;Self&#x2019; with a metatype value must use a &#x2018;required&#x2019; initializer&#x201D; error message as shown in this image:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/09/LineDesigInitReqd.png" alt="Best Practices for Building Swift Classes" width="955" height="105" class="aligncenter size-full wp-image-14058" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/LineDesigInitReqd.png 955w, https://www.appcoda.com/content/images/wordpress/2018/09/LineDesigInitReqd-200x22.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/LineDesigInitReqd-600x66.png 600w, https://www.appcoda.com/content/images/wordpress/2018/09/LineDesigInitReqd-768x84.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/LineDesigInitReqd-860x95.png 860w, https://www.appcoda.com/content/images/wordpress/2018/09/LineDesigInitReqd-680x75.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/LineDesigInitReqd-400x44.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/LineDesigInitReqd-50x5.png 50w" sizes="(max-width: 955px) 100vw, 955px"></p>
<p>Remember that <code>Line</code> subclasses will inherit <code>copy()</code> and the method&#x2019;s implementation is mandated by the <code>Copyable</code> protocol. <code>copy()</code> calls the <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html?ref=appcoda.com#ID217">designated initializer</a>. Note that in the image above, the first character, <code>i</code>, of this <code>init</code> is underlined, telling me that it needs to be marked as <code>required</code> because, according to the official <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html?ref=appcoda.com#ID231">Swift documentation</a>:</p>
<blockquote><p>
  Write the <code>required</code> modifier before the definition of a class initializer to indicate that every subclass of the class must implement that initializer &#x2026; You must also write the <code>required</code> modifier before every subclass implementation of a required initializer, to indicate that the initializer requirement applies to further subclasses in the chain. You do not write the <code>override</code> modifier when overriding a required designated initializer&#x2026;
</p></blockquote>
<p>I marked the designated initializer as <code>required</code> and the code now compiles:</p>
<pre class="swift">
protocol Copyable: class {
    
    func copy() -&gt; Self
    
}

class Line : Copyable {
    
    var beginPoint: CGPoint
    var endPoint: CGPoint
    
    required init( beginPoint: CGPoint, endPoint: CGPoint ) {
        
        self.beginPoint = CGPoint( x: beginPoint.x, y: beginPoint.y )
        self.endPoint = CGPoint( x: endPoint.x, y: endPoint.y )
        
    }
    
    func copy() -&gt; Self {
        
        return type(of: self).init( beginPoint: self.beginPoint,
                                    endPoint: self.endPoint )
        
    }
    
} // end class Line
</pre>
<p>I wrote some test code. I&#x2019;ve taken the output shown in the right pane corresponding to each line of code and made it into a comment:</p>
<pre class="swift">
let line1 = Line(beginPoint: CGPoint(x: 20, y: 20), endPoint: CGPoint(x: 20, y: 200))
let lineCopy = line1.copy()
let line2 = line1
line2.beginPoint.x = 80
// line2.beginPoint = {x 80 y 20}
line1.beginPoint
// line1.beginPoint = {x 80 y 20}
lineCopy.beginPoint
// lineCopy.beginPoint = {x 20 y 20}
</pre>
<p>I initialized an instance of <code>Line</code> and got a reference to it, <code>line1</code>. I got another reference to the <code>Line</code> instance, <code>line2</code>, made and change to one of its properties and, of course, the change is visible in all references.</p>
<p>I used the copy initializer to get an independent <em>copy</em> of my <code>Line</code> instance. That copy is in fact a unique instance. Changing the copy, <code>lineCopy</code>, has no effect on the original instance as referenced by <code>line1</code> and <code>line2</code>.</p>
<p>To further prove my copy initializer, I compared <code>line1</code> and <code>line2</code> with <a href="https://developer.apple.com/documentation/swift/equatable?ref=appcoda.com">&#x201C;the triple-equals identical-to operator (<code>===</code>)&#x201D;</a>. I also compared <code>lineCopy</code> with <code>line1</code> (and didn&#x2019;t bother with <code>line2</code>, because it&#x2019;s identical to <code>line1</code>):</p>
<pre class="swift">
line1 === line2
// true
lineCopy === line1
// false
</pre>
<p><strong><em>Is the copy initializer an initializer?</em></strong><br>
The <code>copy()</code> method you just saw is <em>technically</em> not an initializer, but you see that while it&#x2019;s not called <code>init</code>, it does <em>call</em> <code>init</code>. It&#x2019;s a method that makes a separate, independent <em>copy</em> of a class instance. It <em>doesn&#x2019;t copy</em> a reference, it copies the current contents of an instance&#x2019;s properties and returns a fresh instance of classes that conform to Copyable.</p>
<p>Here&#x2019;s a protocol that indeed requires a by-the-book copy initializer:</p>
<pre class="swift">
protocol Copyable: class
{
    init(copy: Self)
}
</pre>
<p>While this would be my preferred methodology of requiring and creating copy initializers, I&#x2019;ve found that it can cause, in my eyes, unwanted and undue complexities when using inheritance. I&#x2019;m still working on it and will let you know if I get things functioning up to my standards of readability and maintainability.</p>
<p><strong><em>Inheriting the copy initializer</em></strong><br>
Created a descendant with a copy initializer can be little tricky, so let&#x2019;s go ahead and do it to flesh out the concepts required. Let&#x2019;s extend my <code>Line</code> to include some properties that make it easier to draw the line to screen in an iOS app. I&#x2019;ll call the descendant <code>DrawableLine</code>. While the following code looks pretty clean, it does have some issues &#x2014; issues that when resolved will lead to a better understanding of the topics in this tutorial, and for classes in general:</p>
<pre class="swift">
class DrawableLine: Line
{
    
    var color: UIColor
    var width: CGFloat
    
    init( beginPoint: CGPoint, endPoint: CGPoint, color: UIColor, width: CGFloat )
    {
        self.color = color
        self.width = width
        super.init(beginPoint: beginPoint, endPoint: endPoint)
    }
    
    func copy() -&gt; Self
    {
        return type(of: self).init( beginPoint: beginPoint,
                                    endPoint: endPoint,
                                    color: color,
                                    width: width )
    }

} // end class DrawableLine
</pre>
<p>I need to deal with three problems as described by the Swift compiler: &#x201C;&#x2018;required&#x2019; initializer &#x2018;init(beginPoint:endPoint:)&#x2019; must be provided by subclass of &#x2018;Line&#x2019;,&#x201D; &#x201C;Overriding declaration requires an &#x2018;override&#x2019; keyword,&#x201D; and &#x201C;Constructing an object of class type &#x2018;Self&#x2019; with a metatype value must use a &#x2018;required&#x2019; initializer.&#x201D; Here&#x2019;s an image showing the error messages:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors.png" alt="Best Practices for Building Swift Classes" width="1940" height="720" class="aligncenter size-full wp-image-14057" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors.png 1940w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-200x74.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-600x223.png 600w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-768x285.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-1024x380.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-1680x624.png 1680w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-1240x460.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-860x319.png 860w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-680x252.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-400x148.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/ThreeDrawableInheritErrors-50x19.png 50w" sizes="(max-width: 1940px) 100vw, 1940px"></p>
<p>I&#x2019;ll make the required changes and explain them with inline code commentary. Here&#x2019;s the working <code>Line</code> descendant, <code>DrawableLine</code>:</p>
<pre class="swift">
class DrawableLine: Line
{
    
    var color: UIColor
    var width: CGFloat
    
    // We must implement this init tangentially because of Copyable.
    // The &quot;&apos;required&apos; initializer &apos;init(beginPoint:endPoint:)&apos; must
    // be provided by subclass of &apos;Line&apos;&quot; error is then resolved.
    // Think of this as a convenience constructor -- shorthand
    // for rapid prototyping.
    required init( beginPoint: CGPoint, endPoint: CGPoint ) {
        self.color = UIColor.black
        self.width = 1.0
        super.init( beginPoint: beginPoint, endPoint: endPoint )
    }
    
    // Prefxing this init with the &quot;required&quot; keyword resolves the
    // &quot;Constructing an object of class type &apos;Self&apos; with
    // a metatype value must use a &apos;required&apos; initializer&quot; error.
    required init( beginPoint: CGPoint, endPoint: CGPoint, color: UIColor, width: CGFloat )
    {
        self.color = color
        self.width = width
        super.init( beginPoint: beginPoint, endPoint: endPoint )
    }
    
    // Prefixing the method with the &quot;override&quot; keyword resolves the
    // &quot;Overriding declaration requires an &apos;override&apos; keyword&quot; error.
    // We must provide a copy of DrawableLine, not Line.
    override func copy() -&gt; Self
    {
        return type(of: self).init( beginPoint: beginPoint,
                                    endPoint: endPoint,
                                    color: color,
                                    width: width )
    }
    
} // end class DrawableLine
</pre>
<p>Having to implement the <code>required init(beginPoint:endPoint:)</code> in <code>DrawableLine</code> is a small price to pay for the fact that we can keep creating valid copy initializers for each new subclass of <code>Line</code> we dream up in the future. (And it&#x2019;s a heck of a lot better than the side effects I&#x2019;m still wrestling with when using <code>init(copy: Self)</code> and inheritance.)</p>
<p>Regarding the <code>required</code> keyword, remember that when a class adopts a protocol, it <em>must conform to that protocol</em>&#x2026; <strong>AND</strong> remember that a class can have&#x2026; what are they called? <em>Descendents</em>. I once again refer you to the section entitled <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html?ref=appcoda.com#ID231">&#x201C;Required Initializers&#x201D;</a> in the Swift documentation.</p>
<p>Let me test the <code>DrawableLine</code> copy initializer to make sure that changes to a <em>copy</em> of an instance do not affect that instance. Notice that, just for giggles, I used the initializer upon which I commented that it was a &#x201C;convenience constructor &#x2014; shorthand for rapid prototyping.&#x201D;</p>
<pre class="swift">
let thinBlackLine = DrawableLine(beginPoint: CGPoint(x: 187.5, y: 40.0), endPoint: CGPoint(x: 187.5, y: 300.0))
let thinLineCopy = thinBlackLine.copy()
thinLineCopy.color = UIColor.red
thinBlackLine.color
// UIColor.black
thinBlackLine === thinLineCopy
// false
</pre>
<p><strong><em>Drawing my line in a playground</em></strong><br>
Let&#x2019;s draw my <code>thinBlackLine</code> to the simulator in the playground. Delete all the boilerplate code at the bottom of the playground starting with this line:</p>
<pre class="swift">
class MyViewController : UIViewController {...
</pre>
<p>Replace it with the following:</p>
<pre class="swift">
class LineDrawingView: UIView
{
    override func draw(_ rect: CGRect)
    {
        let currGraphicsContext = UIGraphicsGetCurrentContext()
        currGraphicsContext?.setLineWidth(thinBlackLine.width)
        currGraphicsContext?.setStrokeColor(thinBlackLine.color.cgColor)
        // &quot;Begins a new subpath [e.g., line] at the specified point.&quot;
        currGraphicsContext?.move(to: thinBlackLine.beginPoint)
        // &quot;Appends a straight line segment from the current point to the specified point.&quot;
        currGraphicsContext?.addLine(to: thinBlackLine.endPoint)
        // &quot;Paints a line along the current path.&quot;
        currGraphicsContext?.strokePath()
        UIGraphicsEndImageContext()
    }
}

class MyViewController : UIViewController {
    override func loadView() {
        let view = LineDrawingView()
        view.backgroundColor = .white
        self.view = view
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
</pre>
<p>If you need help drawing in a playground, click <a href="http://iosbrain.com/blog/2018/09/03/how-drawing-works-in-an-xcode-playground/?ref=appcoda.com">here</a>. Run the playground and you&#x2019;ll see my line in the &#x201C;Live View&#x201D; pane:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/09/ThinBlackLine.png" alt="Best Practices for Building Swift Classes" width="776" height="1118" class="aligncenter size-full wp-image-14060" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/ThinBlackLine.png 776w, https://www.appcoda.com/content/images/wordpress/2018/09/ThinBlackLine-200x288.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/ThinBlackLine-208x300.png 208w, https://www.appcoda.com/content/images/wordpress/2018/09/ThinBlackLine-768x1106.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/ThinBlackLine-711x1024.png 711w, https://www.appcoda.com/content/images/wordpress/2018/09/ThinBlackLine-680x980.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/ThinBlackLine-400x576.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/ThinBlackLine-50x72.png 50w" sizes="(max-width: 776px) 100vw, 776px"></p>
<h3>Designated initializers</h3>
<p>Notice that I used designated initializers in my code samples so far because I&#x2019;ve got <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html?ref=appcoda.com#ID216">&#x201C;Class Inheritance and Initialization&#x201D;</a> on my mind. I suggest you always craft designated initializers unless there are very extenuating circumstances.</p>
<p><strong>When writing classes, I almost always consider the possibility that I might use inheritance to extend those classes at a later time.</strong> First, <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html?ref=appcoda.com#initialization">consider that</a>:</p>
<blockquote><p>
  <em>Initialization</em> is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.
</p></blockquote>
<p>Some developers skip creating initializers by marking all class member properties as optional. While sometimes it&#x2019;s necessary to use optional member properties, I try to avoid them as much as possible. Most of the time I find that I can design my classes with non-optional member properties. Swift&#x2019;s designers knew that having a designated initializer increases a class&#x2019;s readability, supportability, and potential for future extensibility. It gives you and other developers a lot of insight into your class&#x2019;s purpose and your intent in writing that class. From the <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html?ref=appcoda.com#ID217">Swift docs</a>:</p>
<blockquote><p>
  <em>Designated initializers</em> are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.</p>
<p>  Classes tend to have very few designated initializers, and it is quite common for a class to have only one. Designated initializers are &#x201C;funnel&#x201D; points through which initialization takes place, and through which the initialization process continues up the superclass chain.</p>
<p>  Every class must have at least one designated initializer. In some cases, this requirement is satisfied by inheriting one or more designated initializers from a superclass&#x2026;
</p></blockquote>
<h3>Default initializers</h3>
<p>My next best practice for defining classes comes in the form of another simple protocol:</p>
<pre class="swift">
protocol DefaultInitializable {
    
    init()
    
}
</pre>
<p>Obviously <code>DefaultInitializable</code> requires adopting classes to implement an <code>init()</code> method, what you should recognize as a <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html?ref=appcoda.com#ID213">default initializer</a>.</p>
<p>Suppose your class contains <em>all</em> optional properties but with <em>no explicit</em> default values. Suppose also you have no default initializer. In other words, all your class&#x2019;s properties will be <code>nil</code> right after the Swift-provided default initializer is called. Your new class instance (object) could potentially crash your app. I guarantee that no matter what, somebody at some time is going to initialize one of your classes like this:</p>
<pre class="swift">
class Line {
    
    var beginPoint: CGPoint?
    var endPoint: CGPoint?
    
}

let line = Line() // Line
line.beginPoint // nil
line.endPoint // nil
</pre>
<p>Remember what Swift does in <a href="https://docs.swift.org/swift-book/LanguageGuide/Initialization.html?ref=appcoda.com#ID213">such cases</a>:</p>
<blockquote><p>
  Swift provides a <em>default initializer</em> for any structure or class that provides default values for all of its properties and does not provide at least one initializer itself. The default initializer simply creates a new instance with all of its properties set to their default values. &#x2026;
</p></blockquote>
<p>A strictly optional property with no default value &#x201C;automatically receives a default value of <code>nil</code>, even though this value is not written in the code.&#x201D;</p>
<p>So what happens when the developer that uses the previous code snippet passes  <code>line</code>, <code>line.beginPoint</code>, or <code>line.endPoint</code> to some complex custom code that doesn&#x2019;t check for <code>nil</code>? The code crashes.</p>
<p>That&#x2019;s why <code>DefaultInitializable</code> requires you implement a default initializer (<code>init()</code>). I want you to think through and make semantically clear, in code, the default values your class&#x2019;s properties start out with when that class first becomes an object.</p>
<p>We&#x2019;ll look at an example of <code>DefaultInitializable</code> in the next section. I want to show you how you can compose together as many or as few protocols as needed when defining a class.</p>
<h3>ARC memory management</h3>
<p>When dealing with classes, <a href="http://iosbrain.com/blog/2018/06/07/swift-4-memory-management-via-arc-for-reference-types-classes/?ref=appcoda.com">memory management is handled by ARC</a> and there&#x2019;s always the possibility for <a href="http://iosbrain.com/blog/2018/07/12/fixing-memory-leaks-strong-reference-cycles-in-swift-4/?ref=appcoda.com">memory leaks</a>. I&#x2019;m not proposing a magic cure for leaks, but I&#x2019;m providing you with an <em>aid</em> to track down leaks &#x2014; or at least know how your instances are behaving memory-wise. Here&#x2019;s a protocol and extension that I hope you&#x2019;ll find as useful as I do:</p>
<pre class="swift">
protocol Allocatable: class {
    
    // Give a name to your instance.
    var tag: String { get }
    // Call in initializers.
    func onAllocate()
    // Call in deinitializers.
    func onDeallocate()
    
}

extension Allocatable {
    
    func onAllocate() {
        print(&quot;Instance \(tag) of type \(typeIs()) allocated.&quot;)
    }
    
    func typeIs() -&gt; String {
        return String(describing: type(of: self))
    }
    
    func onDeallocate() {
        print(&quot;Instance \(tag) of type \(typeIs()) deallocated.&quot;)
    }
    
} // end extension Allocatable
</pre>
<p>The <code>tag</code> variable gives you the opportunity to identify individual instances of your classes. I can&#x2019;t magically conjure up a default initializer for your classes, nor can I require a call to <code>deinit</code> in a protocol. So <em>you</em> have to configure your classes to cooperate with my <code>Allocatable</code> protocol.</p>
<p>Here&#x2019;s code where I made a parent class adopt both my <code>DefaultInitializable</code> and <code>Allocatable</code> protocols, including some helpful general inline commentary &#x2014; and comments indicating a few errors I cleaned up as we discussed previously:</p>
<pre class="swift">
protocol Allocatable: class {
    
    // Give a name to your instance.
    var tag: String { get }
    // Call this in initializers.
    func onAllocate()
    // Call this in deinitializers.
    func onDeallocate()
    
}

extension Allocatable {
    
    func onAllocate() {
        print(&quot;Instance \(tag) of type \(typeIs()) allocated.&quot;)
    }
    
    func typeIs() -&gt; String {
        return String(describing: type(of: self))
    }
    
    func onDeallocate() {
        print(&quot;Instance \(tag) of type \(typeIs()) deallocated.&quot;)
    }
    
} // end extension Allocatable

class Line: Allocatable, DefaultInitializable {
    
    var beginPoint: CGPoint
    var endPoint: CGPoint
    let tag: String
    
    // &quot;Initializer requirement &apos;init()&apos; can only be satisfied
    // by a &apos;required&apos; initializer in non-final class &apos;Line&apos;&quot;
    // resolved with &quot;required&quot; prefix
    required init() {
        // Defines a straight vertical line in the upper, center
        // of an iPhone 8
        beginPoint = CGPoint( x: 187.5, y: 40.0 )
        endPoint = CGPoint( x: 187.5, y: 300.0 )
        tag = &quot;Untagged&quot;
        
        onAllocate()
    }
    
    init( beginPoint:CGPoint, endPoint:CGPoint, tag: String ) {
        
        self.beginPoint = CGPoint( x: beginPoint.x, y: beginPoint.y )
        self.endPoint = CGPoint( x: endPoint.x, y: endPoint.y )
        self.tag = tag
        
        onAllocate()
    }
    
    deinit {
        onDeallocate()
    }
    
} // end class Line

class DrawableLine: Line {
    
    var color: UIColor
    var width: CGFloat
    
    // &quot;&apos;required&apos; modifier must be present on all overrides of a
    // required initializer&quot; resolved with &quot;required&quot; prefix
    //
    // &quot;Overriding declaration requires an &apos;override&apos; keyword&quot;
    // resolved when I marked parent init() as &quot;required&quot;
    required init() {
        color = UIColor.black
        width = 1.0
        
        super.init()
    }
    
    required init( beginPoint:CGPoint,
                   endPoint:CGPoint,
                   color: UIColor,
                   width: CGFloat,
                   tag: String ) {
        
        self.color = color
        self.width = width
        
        super.init( beginPoint: beginPoint, endPoint: endPoint, tag: tag )
    }
    
} // end class DrawableLine
</pre>
<p>The next code snippet shows you how my <code>DefaultInitializable</code> protocol encouraged safe usage of class instances created only using their default initializers (look at <code>line</code> and <code>drawableLine3</code>). It also shows you how the designated initializer allowed me to create two fully-configured lines, <code>drawableLine1</code> and <code>drawableLine2</code>:</p>
<pre class="swift">
let line = Line()
let drawableLine1 = DrawableLine(beginPoint: CGPoint(x: 40.0, y: 40.0), endPoint: CGPoint(x: 40.0, y: 300.0), color: UIColor.red, width: 8.0, tag: &quot;Line 1&quot;)
let drawableLine2 = DrawableLine(beginPoint: CGPoint(x: 40.0, y: 300.0), endPoint: CGPoint(x: 300.0, y: 300.0), color: UIColor.red, width: 8.0, tag: &quot;Line 2&quot;)
let drawableLine3 = DrawableLine()
</pre>
<p>Then I wrote code to render those lines in a <code>CGContext</code>&#x2026;</p>
<pre class="swift">
class LineDrawingView: UIView
{
    override func draw(_ rect: CGRect)
    {
        let currGraphicsContext = UIGraphicsGetCurrentContext()
        
        currGraphicsContext?.setLineWidth(drawableLine1.width)
        currGraphicsContext?.setStrokeColor(drawableLine1.color.cgColor)
        // &quot;Begins a new subpath [e.g., line] at the specified point.&quot;
        currGraphicsContext?.move(to: drawableLine1.beginPoint)
        // &quot;Appends a straight line segment from the current point to the specified point.&quot;
        currGraphicsContext?.addLine(to: drawableLine1.endPoint)
        // &quot;Paints a line along the current path.&quot;
        currGraphicsContext?.strokePath()
        
        currGraphicsContext?.setLineWidth(drawableLine2.width)
        currGraphicsContext?.setStrokeColor(drawableLine2.color.cgColor)
        // &quot;Begins a new subpath [e.g., line] at the specified point.&quot;
        currGraphicsContext?.move(to: drawableLine2.beginPoint)
        // &quot;Appends a straight line segment from the current point to the specified point.&quot;
        currGraphicsContext?.addLine(to: drawableLine2.endPoint)
        // &quot;Paints a line along the current path.&quot;
        currGraphicsContext?.strokePath()

        currGraphicsContext?.setLineWidth(drawableLine3.width)
        currGraphicsContext?.setStrokeColor(drawableLine3.color.cgColor)
        // &quot;Begins a new subpath [e.g., line] at the specified point.&quot;
        currGraphicsContext?.move(to: drawableLine3.beginPoint)
        // &quot;Appends a straight line segment from the current point to the specified point.&quot;
        currGraphicsContext?.addLine(to: drawableLine3.endPoint)
        // &quot;Paints a line along the current path.&quot;
        currGraphicsContext?.strokePath()

        UIGraphicsEndImageContext()
    }
}

class MyViewController : UIViewController {
    override func loadView() {
        let view = LineDrawingView()
        view.backgroundColor = .white
        self.view = view
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
</pre>
<p>&#x2026; and displayed those lines in the Simulator:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/09/RedAngleWBlackLine.png" alt="Best Practices for Building Swift Classes" width="782" height="1158" class="aligncenter size-full wp-image-14059" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/RedAngleWBlackLine.png 782w, https://www.appcoda.com/content/images/wordpress/2018/09/RedAngleWBlackLine-200x296.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/RedAngleWBlackLine-203x300.png 203w, https://www.appcoda.com/content/images/wordpress/2018/09/RedAngleWBlackLine-768x1137.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/RedAngleWBlackLine-692x1024.png 692w, https://www.appcoda.com/content/images/wordpress/2018/09/RedAngleWBlackLine-680x1007.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/RedAngleWBlackLine-400x592.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/RedAngleWBlackLine-50x74.png 50w" sizes="(max-width: 782px) 100vw, 782px"></p>
<p>The following sample code will show you how, using <a href="http://iosbrain.com/blog/2018/06/07/swift-4-memory-management-via-arc-for-reference-types-classes/?ref=appcoda.com#arc_local_scope">local scope</a> in a playground, my <code>Allocatable</code> protocol allows you to track ARC memory allocation and deallocation:</p>
<pre class="swift">
do {
    let line = Line()
    let drawableLine1 = DrawableLine(beginPoint: CGPoint(x: 40.0, y: 40.0), endPoint: CGPoint(x: 40.0, y: 300.0), color: UIColor.red, width: 8.0, tag: &quot;Line 1&quot;)
    let drawableLine2 = DrawableLine(beginPoint: CGPoint(x: 40.0, y: 300.0), endPoint: CGPoint(x: 300.0, y: 300.0), color: UIColor.red, width: 8.0, tag: &quot;Line 2&quot;)
    let drawableLine3 = DrawableLine()
}
</pre>
<p>Here is the playground output to console:</p>
<pre class="swift">
Instance Untagged of type Line allocated.
Instance Line 1 of type DrawableLine allocated.
Instance Line 2 of type DrawableLine allocated.
Instance Untagged of type DrawableLine allocated.
Instance Untagged of type DrawableLine deallocated.
Instance Line 2 of type DrawableLine deallocated.
Instance Line 1 of type DrawableLine deallocated.
Instance Untagged of type Line deallocated.
</pre>
<h3>Conformance to Equatable</h3>
<p>You should always be able to determine if the <em>properties</em> of one instance of a class are the same as, or different than, those of another instance, especially because of the possibility of unintended mutation.</p>
<p>First of all, remember that you can always definitively determine if several different references of the same type refer to the same instance (object) using the <a href="https://swiftdoc.org/v4.2/operator/eqeqeq/?ref=appcoda.com">&#x201C;identical-to operator,&#x201D;</a> more commonly known as <code>===</code>.</p>
<p>But suppose you&#x2019;ve used your copy initializer to save a baseline of the values of you used to create the original object. Suppose later you want to see how far the original object&#x2019;s values have strayed from their baseline values.</p>
<p>Or consider that you&#x2019;ve got many different instances of classes and you need the ability to compare their property values for some business requirement (e.g., to find a last name match in a group of object&#x2019;s representing persons). <code>Equatable</code> is an essential protocol (tool) to have. If you don&#x2019;t remember <code>Equatable</code>, see <a href="http://iosbrain.com/blog/2018/01/02/understanding-swift-4-generics-and-applying-them-to-your-code/?ref=appcoda.com#conform-protocol">my explanation here</a> and <a href="https://developer.apple.com/documentation/swift/equatable?ref=appcoda.com">Apple&#x2019;s here</a>.</p>
<p>So I added <code>Equatable</code> conformance to my <code>Line</code> class (which already conforms to <code>Allocatable</code> and <code>DefaultInitializable</code>). I kept it simple when determining whether <code>Line</code> instances were equal (and note that <code>Equatable</code> provides <code>!=</code>). I used the Pythagorean Theorem (see <a href="https://orion.math.iastate.edu/dept/links/formulas/form2.pdf?ref=appcoda.com">here</a> and <a href="http://www.mathwarehouse.com/algebra/distance_formula/index.php?ref=appcoda.com">here</a>) to determine and compare the <em>length</em> of two lines. Here&#x2019;s the new <code>Line</code> code, which is inherited by <code>DrawableLine</code>:</p>
<pre class="swift">
class Line: Allocatable, DefaultInitializable, Equatable {
    
    var beginPoint: CGPoint
    var endPoint: CGPoint
    let tag: String
    
    // &quot;Initializer requirement &apos;init()&apos; can only be satisfied
    // by a &apos;required&apos; initializer in non-final class &apos;Line&apos;&quot;
    // resolved with &quot;required&quot; prefix
    required init() {
        // Defines a straight vertical line in the upper, center
        // of an iPhone 8
        beginPoint = CGPoint( x: 187.5, y: 40.0 )
        endPoint = CGPoint( x: 187.5, y: 300.0 )
        tag = &quot;Untagged&quot;
        
        onAllocate()
    }
    
    init( beginPoint:CGPoint, endPoint:CGPoint, tag: String ) {
        
        self.beginPoint = CGPoint( x: beginPoint.x, y: beginPoint.y )
        self.endPoint = CGPoint( x: endPoint.x, y: endPoint.y )
        self.tag = tag
        
        onAllocate()
    }
    
    // The line length formula is based on the Pythagorean theorem.
    func length () -&gt; CGFloat
    {
        let length = sqrt( pow(endPoint.x - beginPoint.x, 2) + pow(endPoint.y - beginPoint.y, 2) )
        return length
    }
    
    static func == ( lhs: Line, rhs: Line ) -&gt; Bool {
        return (lhs.length() == rhs.length())
    }

    deinit {
        onDeallocate()
    }
    
} // end class Line
</pre>
<p>Here&#x2019;s some code to test my <code>Equatable</code> implementation, including the playground&#x2019;s evaluation of each statement in the right-hand pane which I copied into comments next to each line below:</p>
<pre class="swift">
drawableLine1 == drawableLine3 // true
drawableLine1 != drawableLine3 // false
drawableLine1 == drawableLine2 // true
</pre>
<p>Look at the image above and the values I used in initializers in a previous code snippet above to compare and validate line lengths and results.</p>
<h2>Conclusion</h2>
<p>No matter what paradigm you&#x2019;re using, you need to have a set of <em>best practices</em>. Anybody can take a good tool and screw it all up. Successful developers get to know a technology like OOP through study and practice, practice, practice &#x2014; writing <em>lots</em> of code. They&#x2019;re willing to learn from their mistakes and admit when they&#x2019;re wrong. They&#x2019;re also willing to listen to mentors and/or the collective wisdom of their peers and adopt best practices.</p>
<p>I&#x2019;ve presented you with some best practices for classes using constructs like copy initializers, default initializers, designated initializers, deinitializers, and conformance to the <code>Equatable</code> protocol. This is not an <em>exhaustive</em> list, for example, I could&#x2019;ve covered failable initializers (<code>init?()</code>), but can&#x2019;t cover everything in one article. I hope they help you. At least try them out. You can find an enormous amount of advice on OOP out there, even for a relatively new language like Swift.</p>
<p>Get out out there and experiment, practice, study, and be your best!</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>Let&#x2019;s talk about creating a list on steroids, i.e., a generic doubly linked list in Swift. For our purposes here, a <em>list</em> is a software receptacle that contains related data that we&#x2019;re interested in inspecting, organizing, manipulating, etc. A doubly linked list stores a list</p>]]></description><link>https://www.appcoda.com/pop-generic-doubly-linked-list/</link><guid isPermaLink="false">66612a0f166d3c03cf01147d</guid><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Mon, 24 Sep 2018 00:12:31 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2018/09/kaleidico-754428-unsplash.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->
<img src="https://www.appcoda.com/content/images/wordpress/2018/09/kaleidico-754428-unsplash.jpg" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List"><p>Let&#x2019;s talk about creating a list on steroids, i.e., a generic doubly linked list in Swift. For our purposes here, a <em>list</em> is a software receptacle that contains related data that we&#x2019;re interested in inspecting, organizing, manipulating, etc. A doubly linked list stores a list of &#x201C;nodes.&#x201D; Each node contains data, knows about the preceding node in the list, and knows about the following node in the list.</p>
<p>We&#x2019;ll talk about adding nodes to the list, removing nodes from the list, displaying information stored in nodes in the list, and traversing the list. I&#x2019;ve used the term <em>generic</em> because you&#x2019;ll see that I can store store pretty much every built-in or custom Swift type in my linked list, like <code>Double</code>, <code>UINavigationController</code>, <code>Int</code>, <code>CGFloat</code>, <code>UIView</code>, <code>CGAffineTransform</code>&#x2026; You can even store a collection of instances of a custom class or struct in my list (see section <strong>&#x201C;Storing custom types&#x201D;</strong> below). Most importantly, I&#x2019;ll show you how to move towards generic programming, also known as <em>generics</em>, <em>parametric polymorphism</em>, <em>templates</em>, or <em>parameterized types</em>, where, when possible, we can write code that applies to many types, and thus reduces code redundancy.</p>
<p>To achieve these lofty goals, I&#x2019;ve concentrated my functionality into protocols and classes, taking advantage of both protocol-oriented programming principles (POP) and object-oriented programming principles (OOP). Click here for an <a href="https://www.appcoda.com/protocol-oriented-programming/">introduction to POP</a>. Since I&#x2019;ve discussed POP so much already on AppCoda, I&#x2019;m not going to keep making my case for it&#x2019;s benefits yet again. Please check out my <a href="https://www.appcoda.com/author/andrewjaffee/">previous articles</a> if you need a refresher.</p>
<h2>The possibilities</h2>
<p>I&#x2019;ve written all the code shown in this tutorial in an Xcode playground available on <a href="https://github.com/appcoda/Dynamic-Linked-List?ref=appcoda.com">GitHub</a>. Please download this playground so you can follow along.</p>
<p>As a teaser, to get your interest up, let me show you for real how my generic doubly linked list can store and let you manipulate any Swift type &#x2014; and even allow you to take advantage of <a href="http://iosbrain.com/blog/2017/03/07/polymorphism-in-swift-3-manipulate-multiple-related-controls-with-one-iboutlet-and-one-ibaction/?ref=appcoda.com">OOP polymorphism</a>. Watch as I create a linked list of <em>class</em> type <a href="https://developer.apple.com/documentation/uikit/uicontrol?ref=appcoda.com"><code>UIControl</code></a>, add instances of <em>class</em> types like <code>UITextField</code>, <code>UIStepper</code>, and <code>UIButton</code>, take advantage of the fact that all the latter types are descendents of <code>UIControl</code>, and manipulate those controls. Here&#x2019;s a snippet of code from my playground:</p>
<pre class="swift">do {

    // Instantiate various UIControls.
    let textField : UITextField = UITextField()
    let slider : UISlider = UISlider()
    let segmented : UISegmentedControl = UISegmentedControl()
    let stepper: UIStepper = UIStepper()
    let button: UIButton = UIButton()

    // Create a linked list of type UIControl.
    var uiControlList = LinkedList()
    
    // Append and insert various UIControl descendents as
    // nodes to linked list, giving each a meaningful tag.
    uiControlList.append(Node(with: textField, named: &quot;text field&quot;))
    uiControlList.append(Node(with: slider, named: &quot;slider&quot;))
    uiControlList.append(Node(with: segmented, named: &quot;segmented&quot;))
    uiControlList.insert(Node(with: button, named: &quot;button&quot;), after: &quot;slider&quot;)
    uiControlList.append(Node(with: stepper, named: &quot;stepper&quot;))
    
    // Manipulate UIControl descendents using subscript.
    uiControlList[&quot;slider&quot;]?.payload?.isEnabled = true
    uiControlList[&quot;stepper&quot;]?.payload?.frame // &quot;Show Result&quot;
    uiControlList[&quot;text field&quot;]?.payload?.textInputMode
    uiControlList[&quot;segmented&quot;]?.payload?.setNeedsDisplay()
    
    // Print tags of all nodes in linked list
    // in their current ordering from &quot;head&quot; to
    // &quot;tail.&quot;
    uiControlList.showAll()
    
}
</pre>
<p>Notice that I emphasized the word <em>class</em> in the previous discussion to highlight the fact that each <code>Node</code> in my <code>uiControlList</code> instance holds a <em>reference</em> to a <code>UIControl</code>, and therefore I can manipulate &#x2014; <em>mutate</em> &#x2014; each control in the list.</p>
<p>Here&#x2019;s a screenshot showing how I inspected an instance of <code>UIStepper</code> using my playground&#x2019;s &#x201C;Show Result&#x201D; button. Remember that I created an instance of <code>UIStepper</code>, added it to a <code>Node</code> in my linked list, and then accessed its <a href="https://developer.apple.com/documentation/uikit/uiview/1622621-frame?ref=appcoda.com"><code>frame</code></a> property:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14027" src="https://www.appcoda.com/content/images/wordpress/2018/09/Polymorphic_UIControl_List.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="816" height="440" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Polymorphic_UIControl_List.png 816w, https://www.appcoda.com/content/images/wordpress/2018/09/Polymorphic_UIControl_List-200x108.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Polymorphic_UIControl_List-556x300.png 556w, https://www.appcoda.com/content/images/wordpress/2018/09/Polymorphic_UIControl_List-768x414.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/Polymorphic_UIControl_List-680x367.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Polymorphic_UIControl_List-400x216.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Polymorphic_UIControl_List-50x27.png 50w" sizes="(max-width: 816px) 100vw, 816px"></p>
<p>Since I&#x2019;m using classes, <a href="http://iosbrain.com/blog/2018/06/07/swift-4-memory-management-via-arc-for-reference-types-classes/?ref=appcoda.com">ARC memory management</a> is involved, and I included some code for memory management in my linked list protocol extension. Notice that my console output includes information from <code>print</code> statements I encoded to show the allocation and deallocation of memory for <code>Node</code> class instances stored in my list. I defined <a href="http://iosbrain.com/blog/2018/06/07/swift-4-memory-management-via-arc-for-reference-types-classes/?ref=appcoda.com#arc_local_scope">local scope</a> to force explicit allocation and deallocation. Remember that when developing with classes, you do need to be mindful of memory management. Any time you use reference types (e.g., classes, closures), there is the possibility for <a href="http://iosbrain.com/blog/2018/07/12/fixing-memory-leaks-strong-reference-cycles-in-swift-4/?ref=appcoda.com">memory leaks</a> which can lead to apps crashing. My code is not leaking:</p>
<pre class="bash">Allocating linked list
Allocating node tagged: [text field]
Appending [text field] to head
Allocating node tagged: [slider]
Appending [slider] to tail
Allocating node tagged: [segmented]
Appending [segmented] to tail
Allocating node tagged: [button]
Inserting [button]
Allocating node tagged: [stepper]
Appending [stepper] to tail

-------------------------
Printing list:

[text field]
[slider]
[button]
[segmented]
[stepper]
-------------------------

Deallocating node tagged: [segmented]
Deallocating node tagged: [button]
Deallocating node tagged: [slider]
Deallocating node tagged: [text field]
Deallocating node tagged: [stepper]
Deallocating linked list
</pre>
<p>We&#x2019;ll see later on how we can make our code more type specific/safe, take advantage of OOP inheritance, and define a <code>class UIControlList: LinkedList&lt;UIControl&gt;</code>.</p>
<h3>Storing custom types</h3>
<p>Suppose you create a value type called <code>Point</code> in which you wish to use to store screen coordinates. Yes, you can store those in my linked list. Here&#x2019;s the code:</p>
<pre class="swift">struct Point {
    
    let x: Int
    let y: Int
    
}

do {
    
    var pointList = LinkedList()

    let point1 = Point(x: 1, y: 1)
    let point2 = Point(x: 2, y: 2)
    let point3 = Point(x: 3, y: 3)

    let node1 = Node(with: point1, named: &quot;point1&quot;)
    let node2 = Node(with: point2, named: &quot;point2&quot;)
    let node3 = Node(with: point3, named: &quot;point3&quot;)
    
    pointList.append(node1)
    pointList.insert(node2, after: &quot;point1&quot;)
    pointList.append(node3)
    
    pointList.showAllInReverse()
    
    pointList.delete(node1)
    
}
</pre>
<p>Here&#x2019;s the console output from running the previous code snippet in my playground:</p>
<pre class="swift">Allocating linked list
Allocating node tagged: [point1]
Allocating node tagged: [point2]
Allocating node tagged: [point3]
Appending [point1] to head
Appending [point2] to tail
Appending [point3] to tail

-------------------------
Printing list in reverse:

[point3]
[point2]
[point1]
-------------------------

Delete head [Optional(&quot;point1&quot;)] with followers
Deallocating node tagged: [point1]
Deallocating node tagged: [point2]
Deallocating node tagged: [point3]
Deallocating linked list
</pre>
<p>Notice that <em>despite</em> the fact that I only deleted one of the three original nodes that I added to <code>pointList</code>, all memory allocated for the nodes referencing the <code>Point</code> instances is freed.</p>
<p>Keep this in mind if using my <code>LinkedList</code> <a href="https://developer.apple.com/swift/blog/?id=10&amp;ref=appcoda.com">with value types</a>, like my <code>Point</code> struct in <code>LinkedList&lt;Point&gt;</code>:</p>
<blockquote><p>The most basic distinguishing feature of a <em>value type</em> is that copying &#x2014; the effect of assignment, initialization, and argument passing &#x2014; creates an <em>independent instance</em> with its own unique copy of its data&#x2026;</p></blockquote>
<h2>Data structures</h2>
<p>Successful programmers know about data structures. I&#x2019;ve found that some developers take them for granted and, while they can use data structures, they don&#x2019;t know much about those same structures. Examples include <a href="https://www.geeksforgeeks.org/data-structures/?ref=appcoda.com">array, stack, queue, and heap</a>. I showed you how to develop POP, fully-functional and generic stack and queue data structures here on AppCoda. Most applications would be useless without data. If you don&#x2019;t know at least the basic internals of some of the most common data structures, you&#x2019;re going to have trouble developing innovative code and, probably of most import, you won&#x2019;t be a decent troubleshooter.</p>
<h3>Theory: The linked list data structure</h3>
<p>A doubly linked list (DLL) is an unsorted collection of related data &#x2014; even a collection of other data structures. Some prefer to call a DLL a &#x201C;sequence&#x201D; of data elements. This data structure stores a <em>list</em> of &#x201C;nodes.&#x201D; Each node stores data (or a reference <em>to</em> data), a reference to the preceding node in the list, and a reference to the following node in the list. Since nodes are not sorted in any particular order and can be handled independently, doubly linked lists are very useful when managing large/many pieces of data.</p>
<p>Some examples of usage of linked lists include memory management of the heap, web browser history that allows you to navigate forward and backwards, and in implementations of queues and stacks.</p>
<p>A DLL is an ideal data structure to use when you don&#x2019;t know how many pieces of data you want to store and you don&#x2019;t care what order in which they&#x2019;re stored (or ordering is <em>less</em> of a concern to you). Since order is irrelevant, adding (appending) and removing nodes can be as cheap as O(1) because of the list&#x2019;s dynamic structure.</p>
<p>Inserting a node into the middle of the list can be as cheap as O(1) if you have a reference to a immediate neighbor node. The same goes for deleting from the middle of the list.</p>
<p>If you don&#x2019;t know where a node is located in the DLL, then deleting it requires finding it first, which could be as expensive as O(n). The same goes for inserting a node at a particular position in the list.</p>
<p>A picture of a DLL with 4 nodes will help you to understand my previous paragraphs on theory. This image should give you an idea of why a DLL is often call a &#x201C;sequence:&#x201D;</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14019" src="https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="2494" height="728" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List.png 2494w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-200x58.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-600x175.png 600w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-768x224.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-1024x299.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-1680x490.png 1680w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-1240x362.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-860x251.png 860w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-680x198.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-400x117.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Doubly_Linked_List-50x15.png 50w" sizes="(max-width: 2494px) 100vw, 2494px"></p>
<p>The blue arrows should prove to you that this list is indeed <em>linked</em> as we can get from one node to the next both forwards <em>and backwards</em>, hence the term &#x201C;doubly linked.&#x201D;</p>
<p>There&#x2019;s a lesson about performance buried in the previous paragraphs: If you want to try to keep your DLL operations at O(1), then keep a node around after inserting it so you&#x2019;ll have its <code>next</code> and <code>previous</code> references (&#x201C;pointers&#x201D;). Similarly, if you&#x2019;ve paid O(n) to find a node, keep a reference to it so you know about its neighbors.</p>
<p>The <code>head.previous</code> <em>always</em> points to <code>nil</code>. The <code>tail.next</code> <em>always</em> points to <code>nil</code>.</p>
<p>FYI: You can understand &#x2014; visualize &#x2014; a &#x201C;simple&#x201D; or &#x201C;singly&#x201D; linked list as the same structure in the preceding diagram <em>without</em> the <code>previous</code> property and thusly <em>without</em> its corresponding <code>previous</code> blue arrow.</p>
<h3>The old debate</h3>
<p>I&#x2019;m not going to fall into the &#x201C;arrays are better and faster than linked lists&#x201D; or conversely, the &#x201C;linked lists are faster and better than arrays&#x201D; arguments. But I will discuss some of the background behind these arguments. I&#x2019;ve been around computer science for 30 years and seen old assumptions cast aside by improvements and optimizations to memory management.</p>
<p>There&#x2019;ve been many times when I encountered the design requirement to store hundreds of thousand up to millions of related items in memory. So the question of whether to use an array, maybe a dictionary, or a linked list was of paramount importance because of performance requirements and/or resource limitations.</p>
<p>It used to be a given that array elements were stored contiguously in memory and that array size had to be stated up front, before the array was used. I&#x2019;m talking about back in the days of C language programming. It was also a given that inserting a new element into the middle of an array was a relatively expensive process, of <a href="http://www.bigocheatsheet.com/?ref=appcoda.com">O(n) complexity</a>.</p>
<p>But now looking at the <a href="https://swiftdoc.org/v4.2/type/array/?ref=appcoda.com">Swift <code>Array</code> documentation</a>, I&#x2019;ve found that sometimes array elements are stored contiguously in memory and sometimes not, depending on the circumstances. The documentation also implies that an operation like insertion or deletion may cost less than O(n) because of a smart array resizing strategy.</p>
<p>I&#x2019;m still thinking about this. If you want to join the nightmare, follow <a href="https://stackoverflow.com/q/840648/6383003?ref=appcoda.com">this link</a>, this <a href="https://en.wikipedia.org/wiki/Big_O_notation?ref=appcoda.com">one</a>, or this <a href="https://www.raywenderlich.com/1172-collection-data-structures-in-swift?ref=appcoda.com">one</a>.</p>
<div class="alert gray"><strong>Note:</strong> Yes, CPUs are getting faster and faster, we&#x2019;ve got hardware and software caching, languages are getting optimizing continuously&#x2026; The debate about array versus linked list will probably continue. Who cares. At some point, you&#x2019;re likely to encounter a linked list in your work. This tutorial is an opportunity for you to learn how linked lists, and how data structures in general, work.</div>
<h2>Doubly linked list implementation in Swift</h2>
<p>Let&#x2019;s build a DLL together in Swift. Remember that a DLL is a collection/sequence of nodes, so we&#x2019;ll start by formally defining a <code>Node</code>. Then we&#x2019;ll build an actual list using nodes, and go through each common linked list operation.</p>
<div class="alert gray"><strong>Note:</strong> There are a lot of DLL implementations out there, many with lots and lots of features. My purpose is not to go crazy here, but to simply introduce you to the concept of linked lists, and show you some extra magic with generics, POP, and OOP. I won&#x2019;t be showing you every possibility out there. So no <em>deleteAfter</em>, <em>deleteBefore</em>, <em>deleteAtIndex</em>, <em>insertBefore</em>, <em>insertAtIndex</em>, blah, blah, blah&#x2026;</div>
<h3>The node</h3>
<p>As you&#x2019;ve probably gleaned already from my previous diagram and discussion, the <em>node</em> is at the heart of a DLL. Let&#x2019;s visualize my <code>Node</code> type:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14025" src="https://www.appcoda.com/content/images/wordpress/2018/09/Node.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="640" height="380" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Node.png 640w, https://www.appcoda.com/content/images/wordpress/2018/09/Node-200x119.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Node-505x300.png 505w, https://www.appcoda.com/content/images/wordpress/2018/09/Node-400x238.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Node-50x30.png 50w" sizes="(max-width: 640px) 100vw, 640px"></p>
<p>Remember that protocols offer reusability in that many other types can adopt them. I&#x2019;ve created the following <code>NodeProtocol</code> because not only does my DLL depend on nodes, but so do many other data structures:</p>
<pre class="swift">protocol NodeProtocol: class {

    associatedtype AnyType
    
    var tag: String? { get }
    var payload: AnyType? { get set }
    var next: Self? { get set }
    var previous: Self? { get set }
    
    init(with payload: AnyType, named tag: String)
}
</pre>
<p>We&#x2019;ll discuss the <code>class</code> restriction on <code>NodeProtocol</code> very soon, but please bear with me. Remember that I&#x2019;m making this DLL generic. From the Swift <a href="https://docs.swift.org/swift-book/LanguageGuide/Generics.html?ref=appcoda.com#ID189">documentation on generics</a>:</p>
<blockquote><p>When defining a protocol, it&#x2019;s sometimes useful to declare one or more associated types as part of the protocol&#x2019;s definition. An <em>associated type</em> gives a placeholder name to a type that is used as part of the protocol. The actual type to use for that associated type isn&#x2019;t specified until the protocol is adopted. Associated types are specified with the <code>associatedtype</code> keyword.</p></blockquote>
<p>Here&#x2019;s my generic node type <code>Node&lt;AnyType&gt;</code>:</p>
<pre class="swift">final class Node: NodeProtocol {

    var tag: String?
    var payload: AnyType?
    var next: Node?
    var previous: Node?
    
    init(with payload: AnyType, named tag: String) {
    
        // Stores a reference when using classes;
        // stores a copy when using value types.
        self.payload = payload
        self.tag = tag
        
        print(&quot;Allocating node tagged: [\(tag)]&quot;)
        
    }
    
    deinit {
        print(&quot;Deallocating node tagged: [\(tag!)]&quot;)
    }
}
</pre>
<p>The <code>AnyType</code> between the angle brackets, as in <code>Node&lt;AnyType&gt;</code>, is a placeholder for some Swift built-in type or some custom type we define and fill in when actually declaring an instance of <code>Node</code>. This <code>&lt;AnyType&gt;</code> notation, plus the fact that <code>Node</code> has adopted <code>NodeProtocol</code> with an <code>associatedtype</code>, means we&#x2019;ll be able to create <code>Node</code> instance&#x2019;s whose <code>payload</code> is literally <em>any type</em>. It also means that the <code>next</code> and <code>previous</code> properties will be references to <code>Node</code> instances proximate to other <code>Node</code> instances in our DLL.</p>
<p>The <code>tag</code> property is an identifier I always use when building DLLs. It makes it easy for me to find and reference <code>Node</code> instances in my DLLs using meaningful names.</p>
<p>The <code>init</code> method includes a <code>print</code> showing <code>Node</code> memory allocation. The <code>deinit</code> method similarly uses <code>print</code> to show <code>Node</code> memory deallocation.</p>
<h3>Why we need reference semantics</h3>
<p>Let&#x2019;s talk about why <code>NodeProtocol</code> is marked as <code>class</code>. The whole concept of a <em>node</em> in a DLL is antithetical to a value type. How could we build a list of <code>Node</code> instances if the their <code>next</code> and <code>previous</code> properties were values that contained only data? It wouldn&#x2019;t even make sense.</p>
<p>In order for us to build a <em>list</em> of <em>linked</em> <code>Node</code> instances, we use <a href="http://iosbrain.com/blog/2018/03/21/protocol-oriented-programming-in-swift-an-introduction/?ref=appcoda.com#ref_sem1">reference semantics</a> and <a href="http://iosbrain.com/blog/2018/06/07/swift-4-memory-management-via-arc-for-reference-types-classes/?ref=appcoda.com">reference types</a>, i.e., classes. The <code>next</code> and <code>previous</code> properties of each <code>Node</code> object/instance <em>must be</em> references to other <code>Node</code> objects/instances.</p>
<p>Making the <code>payload</code> property of a <code>Node</code> into a reference (pointer) affords you flexibility and possibly some efficiency, especially if your list contains large <code>payload</code> items and/or a large number of payload items. You can create objects anywhere and add them as <em>references</em> to the linked list. Your list doesn&#x2019;t actually store copies of data <em>inside</em> the list. It simply stores references to instances you&#x2019;ve already created and are manipulating. If using classes, once there&#x2019;s a reference to whatever type a <code>payload</code> instance points to, the underlying object is kept alive and not deallocated since the reference count to it was increased by one when making it part of a <code>Node</code>.</p>
<p>Here&#x2019;s a visual representation of my DLL storing <code>UIControl</code> instances, as we saw example code for at the beginning of this tutorial:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14026" src="https://www.appcoda.com/content/images/wordpress/2018/09/payload.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="584" height="722" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/payload.png 584w, https://www.appcoda.com/content/images/wordpress/2018/09/payload-200x247.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/payload-243x300.png 243w, https://www.appcoda.com/content/images/wordpress/2018/09/payload-400x495.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/payload-50x62.png 50w" sizes="(max-width: 584px) 100vw, 584px"></p>
<p>Remember that I showed you Apple&#x2019;s definition of a value type at the start of this tutorial in the section entitled &#x201C;The possibilities.&#x201D; I want you to think about this carefully: The behavior of the <code>Node</code> type&#x2019;s <code>payload</code> property is going to exhibit <a href="http://iosbrain.com/blog/2018/03/28/protocol-oriented-programming-in-swift-is-it-better-than-object-oriented-programming/?ref=appcoda.com#value_semantics">value semantics</a> with value types and <a href="http://iosbrain.com/blog/2018/03/21/protocol-oriented-programming-in-swift-an-introduction/?ref=appcoda.com#ref_sem1">reference semantics</a> with reference types. That might sound obvious, but please consider carefully.</p>
<h3>Why my Node class is final</h3>
<p>If I don&#x2019;t mark my <code>Node</code> class as <code>final</code>, I get the following error messages:</p>
<pre class="swift">Protocol &apos;NodeProtocol&apos; requirement &apos;next&apos; cannot be satisfied by a non-final class (&apos;Node&apos;) because it uses &apos;Self&apos; in a non-parameter, non-result type position

Protocol &apos;NodeProtocol&apos; requirement &apos;previous&apos; cannot be satisfied by a non-final class (&apos;Node&apos;) because it uses &apos;Self&apos; in a non-parameter, non-result type position
</pre>
<p>As best as I can understand it, the problem stems from the fact that I&#x2019;m imposing a <code>Self</code> requirement in a protocol, <strong>where <code>Self</code> is used as a <em>type</em> in a declaration</strong>, which is then adopted by a class. In <em>this specific case</em>, I <em>cannot</em> impose a <code>Self</code> requirement via a protocol on classes that are <em>not</em> declared as <code>final</code>. Say I created a non-<code>final</code> class that conformed to a protocol with <code>Self</code> as a type requirement &#x2014; call it <code>ClassParent</code>. If I could create a descendent of the non-<code>final</code> class, call it <code>ClassChild</code>, it would always interpret <code>Self</code> as its parent class, <code>ClassParent</code>, which would be completely incorrect, and would violate the parent&#x2019;s <code>Self</code> requirement stemming from its protocol conformance.</p>
<p>In this case, <code>Self</code> literally means only the conforming class. Parenthetically, my type <code>Node</code> type already can provide linked list node functionality for <em>any</em> type, so what exactly would I gain by overriding the purpose of <code>next</code> and <code>previous</code>? What would <em>subclassing</em> my <code>Node&lt;AnyType&gt;</code> type mean, which already is generic, and where <code>next</code> and <code>previous</code> are defined in the <code>NodeProtocol</code> as instances of <code>Self</code>?</p>
<p>This is getting almost metaphysical, and is beyond the scope of this tutorial. If you want to pursue this topic, I&#x2019;ve found some links you can study that provide explanations and workarounds for the &#x201C;non-final class&#x201D; class error <a href="https://stackoverflow.com/a/49634785/6383003?ref=appcoda.com">here</a>, <a href="https://stackoverflow.com/a/37141531/6383003?ref=appcoda.com">here</a>, and <a href="https://stackoverflow.com/a/37555215/6383003?ref=appcoda.com">here</a>.</p>
<h3>Protocol-oriented linked list</h3>
<p>To make my DLL portable, I defined almost all its functionality in a protocol and protocol extension. Let&#x2019;s have a look and then talk about it. Note that we won&#x2019;t look at the protocol extension&#x2019;s contents until later:</p>
<pre class="swift">protocol LinkedListProtocol {
    
    associatedtype AnyType
    
    var head: Node? { get set }
    var tail: Node? { get set }
    mutating func append(_ newNode: Node)
    mutating func insert(_ newNode: Node, after nodeWithTag: String)
    mutating func delete(_ node: Node)
    func showAll()
    func showAllInReverse()
    subscript(tag: String) -&gt; Node? { get }
    func prepareForDealloc()
    
}

extension LinkedListProtocol {
    
    // THERE&apos;S A BUNCH OF CODE HERE.
    
...

} // end extension LinkedListProtocol

class LinkedList : LinkedListProtocol {
    
    var head: Node?
    var tail: Node?
    
    init() {
        head = nil
        tail = head
        print(&quot;Allocating linked list&quot;)
    }
    
    deinit {
        prepareForDealloc()
        head = nil
        tail = nil
        print(&quot;Deallocating linked list&quot;)
    }
    
} // end class LinkedList
</pre>
<p>Again, the <code>&lt;AnyType&gt;</code> notation, as in <code>LinkedList&lt;AnyType&gt;</code>, plus the fact that <code>LinkedList</code> has adopted <code>LinkedListProtocol</code> with an <code>associatedtype</code>, means we&#x2019;ll be able to create <code>LinkedList</code> instance&#x2019;s that can store sequences of any type. Remember how I instantiated an instance of <code>LinkedList&lt;UIControl&gt;</code> at the beginning of this tutorial?</p>
<p>Notice that even though a DLL is unsorted, it still is a <em>sequence</em> of <code>Node</code> instances. That&#x2019;s important to understand because, when we don&#x2019;t know where we are in the list, we&#x2019;ve got to be able to &#x201C;travel&#x201D; across the sequence of nodes in order to find a node.</p>
<h3>Use case for explaining code</h3>
<p>I wrote several rounds of code that exercises my DLL functionality in the protocol, protocol extension, and class we just reviewed. Note that <em>all</em> functionality for my DLL is expressed in the <code>LinkedListProtocol</code> extension. The following code will help us to discuss the extension&#x2019;s methods:</p>
<pre class="swift">do {
    
    print(&quot;in local scope&quot;)
    // declare a linked list of type UIView
    // and initialize it
    var linkedList = LinkedList()
    
    // create some nodes to be added to my list,
    // initializing each with a UIVIew and tag/name
    let node1 = Node(with: 1.0, named: &quot;Double 1.0&quot;)
    let node2 = Node(with: 2.0, named: &quot;Double 2.0&quot;)
    let node2_2 = Node(with: 2.2, named: &quot;Double 2.2&quot;)
    let node3 = Node(with: 3.0, named: &quot;Double 3.0&quot;)
    let node4 = Node(with: 4.0, named: &quot;Double 4.0&quot;)
    let node5 = Node(with: 5.0, named: &quot;Double 5.0&quot;)

    // add the nodes to my linked list
    linkedList.append(node1)
    linkedList.append(node2)
    linkedList.append(node3)
    linkedList.insert(node2_2, after: &quot;Double 2.0&quot;)
    linkedList.append(node4)
    linkedList.append(node5)
    
    // test the subscript
    linkedList[&quot;Double 3.0&quot;]?.tag
    // &quot;Double 3.0&quot;
    
    // print the list to console
    linkedList.showAll()
    
    // print the list to console in reverse
    linkedList.showAllInReverse()

    // delete nodes in random order
    linkedList.delete(node3)
    linkedList.delete(node1)
    linkedList.delete(node2_2)
    linkedList.delete(node4)
    linkedList.delete(node5)
    linkedList.delete(node2)
    
    // show empty list
    linkedList.showAll()
    
}
</pre>
<p>Here&#x2019;s the playground console output corresponding to the code I just showed you:</p>
<pre class="swift">in local scope
Allocating linked list
Allocating node tagged: [Double 1.0]
Allocating node tagged: [Double 2.0]
Allocating node tagged: [Double 2.2]
Allocating node tagged: [Double 3.0]
Allocating node tagged: [Double 4.0]
Allocating node tagged: [Double 5.0]
Appending [Double 1.0] to head
Appending [Double 2.0] to tail
Appending [Double 3.0] to tail
Inserting [Double 2.2]
Appending [Double 4.0] to tail
Appending [Double 5.0] to tail

-------------------------
Printing list:

[Double 1.0]
[Double 2.0]
[Double 2.2]
[Double 3.0]
[Double 4.0]
[Double 5.0]
-------------------------


-------------------------
Printing list in reverse:

[Double 5.0]
[Double 4.0]
[Double 3.0]
[Double 2.2]
[Double 2.0]
[Double 1.0]
-------------------------

Delete internal node: [Optional(&quot;Double 3.0&quot;)]
Delete head [Optional(&quot;Double 1.0&quot;)] with followers
Delete internal node: [Optional(&quot;Double 2.2&quot;)]
Delete internal node: [Optional(&quot;Double 4.0&quot;)]
Delete tail [Optional(&quot;Double 5.0&quot;)] with predecessors
Delete head [Optional(&quot;Double 2.0&quot;)]

-------------------------
Printing list:

-------------------------

Deallocating node tagged: [Double 5.0]
Deallocating node tagged: [Double 4.0]
Deallocating node tagged: [Double 3.0]
Deallocating node tagged: [Double 2.2]
Deallocating node tagged: [Double 2.0]
Deallocating node tagged: [Double 1.0]
Deallocating linked list
</pre>
<h3>When using a DLL, <em>always</em>&#x2026;</h3>
<p>Remember to <em>always</em> think about a <code>Node</code> instance&#x2019;s <code>next</code> and <code>previous</code> references when adding/deleting that node to/from the list <em>and</em> when traversing the list. What do we always say? &#x201C;The <code>head.previous</code> <em>always</em> points to <code>nil</code>. The <code>tail.next</code> <em>always</em> points to <code>nil</code>.&#x201D; Refer to my diagram of the DLL up above as many times as you need.</p>
<h3>Initializing the DLL</h3>
<p>Initially, a newly-instantiated <code>LinkedList</code> object has a <code>head</code> and <code>tail</code> that are both <code>nil</code>:</p>
<pre class="swift">    init() {
        head = nil
        tail = head
        print(&quot;Allocating linked list&quot;)
    }
</pre>
<h3>Adding &#x2014; appending &#x2014; a Node</h3>
<p>The first time we add a <code>Node</code> to the DLL, it becomes the <code>head</code>. At this point, the <code>head</code> is the same as the <code>tail</code>. After appending the first <code>Node</code>, we subsequently add <code>Node</code> instances to the <code>tail</code>. This just makes common sense and is the prevailing convention. Appending is always cheap. It&#x2019;s O(1):</p>
<pre class="swift">...
extension LinkedListProtocol {
    
    mutating func append(_ newNode: Node) {
        
        if let tailNode = tail {
            
            print(&quot;Appending [\(newNode.tag!)] to tail&quot;)
            tailNode.next = newNode
            newNode.previous = tailNode
            
        }
        else {
            
            print(&quot;Appending [\(newNode.tag!)] to head&quot;)
            head = newNode
            
        } // end else
        
        tail = newNode
        
    } // end func append
...
</pre>
<h3>Deleting a Node</h3>
<p>I&#x2019;ve only written code for deleting nodes if you <em>already</em> have a reference to a <code>Node</code> instance, which makes my <code>delete</code> method cheap at O(1). I could&#x2019;ve gone on forever writing specialized methods like <code>deleteAfter</code>, <code>deleteBefore</code>, <code>deleteAtIndex</code>, etc., but I didn&#x2019;t because the purpose here is to learn how a linked list works in general. Note that my code makes sure there are no strong references vis-a-vis <code>next</code> and <code>previous</code> properties of <code>Node</code> instances when that instance is removed from the list.</p>
<p>Here&#x2019;s the deletion code and then we&#x2019;ll discuss:</p>
<pre class="swift">...
    mutating func delete(_ node: Node) {
        
        // Remove the head?
        if node.previous == nil {
            
            if let nodeAfterDeleted = node.next {
                
                print(&quot;Delete head [\(node.tag)] with followers&quot;)
                nodeAfterDeleted.previous = nil
                head?.next = nil
                head = nil
                head = nodeAfterDeleted
                
                node.next = nil
                node.previous = nil
                
            }
            else
            {
                
                print(&quot;Delete head [\(node.tag)]&quot;)
                head = nil
                tail = nil
                
                node.next = nil
                node.previous = nil
                
            }
            
        } // end remove head
            
        // Remove the tail?
        else if node.next == nil {
            
            if let deletedPreviousNode = node.previous {
                
                print(&quot;Delete tail [\(node.tag)] with predecessors&quot;)
                deletedPreviousNode.next = nil
                tail?.previous = nil
                tail = nil
                node.next = nil
                tail = deletedPreviousNode
                
                node.next = nil
                node.previous = nil
                
            }
            else {
                
                print(&quot;Delete tail [\(node.tag)]&quot;)
                head = nil
                tail = nil
                
                node.next = nil
                node.previous = nil
                
            }
            
        } // end remove tail
            
        // Remove node BETWEEN head and tail?
        else {
            
            if let deletedPreviousNode = node.previous,
                let deletedNextNode = node.next {
                
                node.next = nil
                node.previous = nil
                print(&quot;Delete internal node: [\(node.tag)]&quot;)
                
                deletedPreviousNode.next = deletedNextNode
                deletedNextNode.previous = deletedPreviousNode
                
            }
            
        } // end remove in-between node
        
    } // end func delete
...
</pre>
<p><strong><em>Deleting the <code>head</code></em></strong><br>
The <code>head.previous</code> <em>always</em> points to <code>nil</code>. Remember that and everything in the section entitled <strong>&#x201C;When using a DLL, <em>always</em>&#x2026;&#x201D;</strong> and you&#x2019;ll understand.</p>
<p><strong><em>Deleting the <code>tail</code></em></strong><br>
The <code>tail.next</code> <em>always</em> points to <code>nil</code>. Remember that and everything in the section entitled <strong>&#x201C;When using a DLL, <em>always</em>&#x2026;&#x201D;</strong> and you&#x2019;ll understand.</p>
<p><strong><em>Deleting a node in the &#x201C;middle&#x201D; of the list</em></strong><br>
Say we want to delete some <code>Node</code> instance that is somewhere in the &#x201C;middle&#x201D; of our DLL. In other words, it has neighbors and is not the <code>head</code> or <code>tail</code>. Here&#x2019;s the <code>Node</code> instance to delete:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14015" src="https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="1376" height="344" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1.png 1376w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1-200x50.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1-600x150.png 600w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1-768x192.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1-1024x256.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1-1240x310.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1-860x215.png 860w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1-680x170.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1-400x100.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_1-50x13.png 50w" sizes="(max-width: 1376px) 100vw, 1376px"></p>
<p>Let&#x2019;s save references to the <code>Node</code> instances that precede and follow the <code>Node</code> to be deleted. These are obtained from the <code>previous</code> and <code>next</code> properties of the <code>Node</code> to be deleted:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14016" src="https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="1366" height="394" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2.png 1366w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2-200x58.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2-600x173.png 600w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2-768x222.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2-1024x295.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2-1240x358.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2-860x248.png 860w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2-680x196.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2-400x115.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_2-50x14.png 50w" sizes="(max-width: 1366px) 100vw, 1366px"></p>
<p>Let&#x2019;s assign <code>nil</code> to the about-to-be-deleted node&#x2019;s <code>next</code> and <code>previous</code> properties so they won&#x2019;t hold strong references to neighboring <code>Node</code> instances and thus won&#x2019;t interfere with their eventual ARC deallocation:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14017" src="https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="1368" height="454" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3.png 1368w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3-200x66.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3-600x199.png 600w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3-768x255.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3-1024x340.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3-1240x412.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3-860x285.png 860w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3-680x226.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3-400x133.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_3-50x17.png 50w" sizes="(max-width: 1368px) 100vw, 1368px"></p>
<p>Finally, let&#x2019;s take the deleted <code>Node</code> out of the sequence completely. We make its formerly preceding <code>Node</code> instance&#x2019;s <code>next</code> property point to its formerly following <code>Node</code>. We make its formerly following <code>Node</code> instance&#x2019;s <code>previous</code> property point to its formerly preceding <code>Node</code>. Here it is:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14018" src="https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="1376" height="678" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4.png 1376w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4-200x99.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4-600x296.png 600w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4-768x378.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4-1024x505.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4-1240x611.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4-860x424.png 860w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4-680x335.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4-400x197.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Delete_Mid_4-50x25.png 50w" sizes="(max-width: 1376px) 100vw, 1376px"></p>
<h3>Inserting a Node</h3>
<p>I&#x2019;ve limited my DLL <em>insertion</em> functionality, not to be confused with <em>appending</em>, to inserting a <code>Node</code> immediately after a known and preexisting <code>Node</code>. First we use the traversal logic, covered in the next section, to find the <code>Node</code> with a given <code>tag</code>. This means my insertion cost can be up to O(n). We know that we&#x2019;ll insert the new <code>Node</code> <em>after</em> the <code>Node</code> we found with <code>tag</code>. I&#x2019;ll cover the case of inserting a new <code>Node</code> in the &#x201C;middle&#x201D; of the list and leave the single edge case, that of inserting right after <code>head</code>, for you to glean from all the other explanations and info shown herein.</p>
<p>This all boils down to <strong>1)</strong> configuring the <code>next</code> and <code>previous</code> references of the new <code>Node</code>, <strong>2)</strong> configuring the <code>next</code> reference of the new node&#x2019;s preceding neighbor, and <strong>3)</strong> configuring the <code>previous</code> reference of the new node&#x2019;s following neighbor, like so:</p>
<p>This just shows the new node:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14020" src="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After0.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="756" height="626" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After0.png 756w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After0-200x166.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After0-362x300.png 362w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After0-680x563.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After0-400x331.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After0-50x41.png 50w" sizes="(max-width: 756px) 100vw, 756px"></p>
<p>Here are steps <strong>1</strong>, <strong>2</strong>, and <strong>3</strong>:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14021" src="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After1.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="754" height="630" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After1.png 754w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After1-200x167.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After1-359x300.png 359w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After1-680x568.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After1-400x334.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After1-50x42.png 50w" sizes="(max-width: 754px) 100vw, 754px"></p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14022" src="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After2.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="746" height="660" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After2.png 746w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After2-200x177.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After2-339x300.png 339w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After2-680x602.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After2-400x354.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After2-50x44.png 50w" sizes="(max-width: 746px) 100vw, 746px"></p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14023" src="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After3.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="754" height="662" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After3.png 754w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After3-200x176.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After3-342x300.png 342w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After3-680x597.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After3-400x351.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After3-50x44.png 50w" sizes="(max-width: 754px) 100vw, 754px"></p>
<p>Finally, we have:</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-14024" src="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4.png" alt="Protocol-oriented Data Structures in Swift: A Generic Doubly Linked List" width="1258" height="618" srcset="https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4.png 1258w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4-200x98.png 200w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4-600x295.png 600w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4-768x377.png 768w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4-1024x503.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4-1240x609.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4-860x422.png 860w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4-680x334.png 680w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4-400x197.png 400w, https://www.appcoda.com/content/images/wordpress/2018/09/Node_Insert_After4-50x25.png 50w" sizes="(max-width: 1258px) 100vw, 1258px"></p>
<p>Here&#x2019;s the insertion code:</p>
<pre class="swift">...
    mutating func insert(_ newNode: Node, after nodeWithTag: String) {
        
        if head == nil {
            return
        }
            
        else {
            
            var currentNode = head
            
            while currentNode != nil {
                
                if nodeWithTag == currentNode?.tag {
                    
                    // If the current node with matching tag is
                    // NOT the tail...
                    if currentNode?.next != nil {
                        
                        // ... then insert new node &quot;after&quot;
                        // the current node.
                        let newNextNode = currentNode?.next
                        currentNode?.next = newNode
                        newNextNode?.previous = newNode
                        newNode.previous = currentNode
                        newNode.next = newNextNode
                        currentNode = nil
                        print(&quot;Inserting [\(newNode.tag!)]&quot;)
                        
                    }
                    else { // Append to list with single head
                           // (which means tail = head).
                        
                        append(newNode)
                        currentNode = nil
                        
                    }
                    
                } // end if nodeWithTag == currentNode?.tag
                    
                else {
                    currentNode = currentNode?.next
                }
                
            } // end while
            
        } // end else
        
    } // end func insert
...
</pre>
<h3>Traversing the list</h3>
<p>We can <em>traverse</em> the list, going from the beginning to end, by following the trail mapped out by each <code>Node</code> instance&#x2019;s <code>next</code> property, starting at the first <code>Node</code> in the list, known as the <code>head</code>. We use the <code>tag</code> property of each <code>Node</code> to identify it &#x2014; i.e., traverse until we find a <code>tag</code> that matches a <code>String</code> that we used to create (initialize) a <code>Node</code>. We can similarly traverse (and search) our list, going from the end to beginning (in &#x201C;reverse&#x201D;), by following the trail mapped out by each <code>Node</code> instance&#x2019;s <code>previous</code> property, starting at the last <code>Node</code> in the list, known as the <code>tail</code>.</p>
<p>Since traversal means potentially going through every node in the list, that means it is pricey at O(n). Study question: Since you&#x2019;ve got <em>both</em> forward and reverse traversal, can you think of a way to optimize?</p>
<p>After reading the previous prose and looking at the blue arrows in my diagram of a DLL above, you should get the following code:</p>
<pre class="swift">...
    func showAll() {
        
        print(&quot;\n-------------------------&quot;)
        print(&quot;Printing list:\n&quot;)
        
        var nextNode: Node?
        
        if let head = head {
            
            nextNode = head
            
            repeat {
                
                if let tag = nextNode?.tag {
                    print(&quot;[\(tag)]&quot;)
                }
                    
                nextNode = nextNode?.next
                
            } while (nextNode != nil)
            
        } // end if let head = head
        
        print(&quot;-------------------------\n&quot;)
        
    } // end func showAll()
    
    func showAllInReverse()
    {
        
        print(&quot;\n-------------------------&quot;)
        print(&quot;Printing list in reverse:\n&quot;)
        
        var previousNode: Node?
        
        if let tail = tail {
            
            previousNode = tail
            
            repeat {
                
                if let tag = previousNode?.tag {
                    print(&quot;[\(tag)]&quot;)
                }
                
                previousNode = previousNode?.previous
                
            } while (previousNode != nil)
        }
        print(&quot;-------------------------\n&quot;)
        
    } // end func showAllInReverse()
...
</pre>
<h3>List subscript</h3>
<p>I&#x2019;ve implemented a Swift <a href="https://docs.swift.org/swift-book/LanguageGuide/Subscripts.html?ref=appcoda.com"><code>subscript</code></a> using the same logic discussed in the previous section entitled <strong>&#x201C;Traversing the list&#x201D;</strong>. Here, I&#x2019;ve used the <code>tag</code> value of node, a <code>String</code>, as the subscript:</p>
<pre class="swift">...
    subscript(tag: String) -&gt; Node? {
        
        if head == nil {
            return nil
        }
            
        else {
            
            var currentNode = head
            
            while currentNode != nil {
                
                if tag == currentNode?.tag {
                    return currentNode
                }
                else {
                    currentNode = currentNode?.next
                }
                
            } // end while
            
            return nil
            
        } // end else
        
    } // end subscript
...
</pre>
<h3>ARC memory deallocation for DLL</h3>
<p>I hope you noticed my call to <code>LinkedListProtocol</code> extension method <code>prepareForDealloc()</code> in my <code>LinkedList</code> class&#x2019;s <code>deinit</code> method:</p>
<pre class="swift">...
    deinit {
        prepareForDealloc()
        head = nil
        tail = nil
        print(&quot;Deallocating linked list&quot;)
    }
...
</pre>
<p>ARC will <a href="http://iosbrain.com/blog/2018/06/07/swift-4-memory-management-via-arc-for-reference-types-classes/?ref=appcoda.com">only deallocate a class instance from memory</a> if its reference count is zero. As long as there is 1 (one) or more reference(s) to that instance, its memory cannot be deallocated. Since so many references are being used in my DLL code, I wanted to <a href="http://iosbrain.com/blog/2018/07/12/fixing-memory-leaks-strong-reference-cycles-in-swift-4/?ref=appcoda.com">prevent memory leaks</a>.</p>
<p>My <code>prepareForDealloc()</code> method makes sure no <code>Node</code> instances in the DLL hold strong references to each other by starting at the <code>tail</code>, traversing the list in reverse, and setting each <code>Node</code> instance&#x2019;s <code>next</code> and <code>previous</code> properties to <code>nil</code>:</p>
<pre class="swift">...
    // Unlink all nodes so there are no
    // strong references to prevent
    // deallocation.
    func prepareForDealloc() {
        
        var currentNode: Node?
        
        if var tail = tail {
            
            currentNode = tail
            
            repeat {
                
                if let tag = currentNode?.tag {
                    //print(&quot;\(tag)&quot;)
                }
                
                tail = currentNode!
                currentNode = currentNode?.previous
                tail.previous = nil
                tail.next = nil
                
            } while (currentNode != nil) // nil is head
            
        } // end if var tail = tail
        
    } // end func showAllInReverse(
    
} // end extension LinkedListProtocol
...
</pre>
<h2>Inheriting from my <code>LinkedList</code> class</h2>
<p>I wanted to show you that you can specialize my <code>LinkedList</code> class by inheriting from it. In other words, you can create a <em>subclass</em> of <code>LinkedList</code> which is tied to any Swift built-in or custom type. You can use or override existing <code>LinkedListProtocol</code> extension functionality. Most importantly, you can add features that are specific to the type to which you bind the <code>LinkedList</code> subclass.</p>
<p>I rewrote the code shown at the beginning of this tutorial. Instead of simply declaring an instance of the <code>LinkedList</code> class typed for <code>UIControl</code>, which is still pretty powerful, I declared a class inheriting from <code>LinkedList&lt;UIControl&gt;</code>. Let&#x2019;s look at the subclass first:</p>
<pre class="swift">class UIControlList: LinkedList {
    
    func shouldEnable(_ yesOrNo: Bool) {

        if head == nil {
            return
        }
            
        else {
            
            var currentNode = head
            
            while currentNode != nil {
                
                currentNode?.payload?.isEnabled = yesOrNo
                currentNode = currentNode?.next
                
            }
            
        } // end else

    } // end func shouldEnable()
    
    func showAll() {
        
        print(&quot;\n-------------------------&quot;)
        print(&quot;Printing list:\n&quot;)
        
        var nextNode: Node?
        
        if let head = head {
            
            nextNode = head
            
            repeat {
                
                if let tag = nextNode?.tag {
                    print(&quot;[\(tag)]&apos;s status is \(nextNode?.payload?.isEnabled)&quot;)
                }
                
                nextNode = nextNode?.next
                
            } while (nextNode != nil)
            
        } // end if let head = head
        
        print(&quot;-------------------------\n&quot;)
        
    } // end func showAll()
    
} // end class UIControlList
</pre>
<p>Here&#x2019;s code that instantiates and uses the new <code>UIControlList</code> subclass:</p>
<pre class="swift">do {
    
    // Instantiate various UIControls.
    let textField : UITextField = UITextField()
    let slider : UISlider = UISlider()
    let segmented : UISegmentedControl = UISegmentedControl()
    let stepper: UIStepper = UIStepper()
    let button: UIButton = UIButton()
    
    // Create a linked list of type UIControl.
    var uiControlList = UIControlList()
    
    // Append and insert various UIControl descendents as
    // nodes to linked list, giving each a meaningful tag.
    uiControlList.append(Node(with: textField, named: &quot;text field&quot;))
    uiControlList.append(Node(with: slider, named: &quot;slider&quot;))
    uiControlList.append(Node(with: segmented, named: &quot;segmented&quot;))
    uiControlList.insert(Node(with: button, named: &quot;button&quot;), after: &quot;slider&quot;)
    uiControlList.append(Node(with: stepper, named: &quot;stepper&quot;))
    
    // Manipulate UIControl descendents using subscript.
    uiControlList[&quot;slider&quot;]?.payload?.isEnabled = true
    uiControlList[&quot;stepper&quot;]?.payload?.frame // &quot;Show Result&quot;
    uiControlList[&quot;text field&quot;]?.payload?.textInputMode
    uiControlList[&quot;segmented&quot;]?.payload?.setNeedsDisplay()
    
    // Use feature available to all UIControls.
    uiControlList.shouldEnable(true)
    
    // Print tags of all nodes in linked list
    // in their current ordering from &quot;head&quot; to
    // &quot;tail.&quot;
    uiControlList.showAll()
    
}
</pre>
<p>Here&#x2019;s playground console output from the immediately previous code snippet:</p>
<pre class="swift">Allocating linked list
Allocating node tagged: [text field]
Appending [text field] to head
Allocating node tagged: [slider]
Appending [slider] to tail
Allocating node tagged: [segmented]
Appending [segmented] to tail
Allocating node tagged: [button]
Inserting [button]
Allocating node tagged: [stepper]
Appending [stepper] to tail

-------------------------
Printing list:

[text field]&apos;s status is Optional(true)
[slider]&apos;s status is Optional(true)
[button]&apos;s status is Optional(true)
[segmented]&apos;s status is Optional(true)
[stepper]&apos;s status is Optional(true)
-------------------------

Deallocating node tagged: [segmented]
Deallocating node tagged: [button]
Deallocating node tagged: [slider]
Deallocating node tagged: [text field]
Deallocating node tagged: [stepper]
Deallocating linked list
</pre>
<h2>Conclusion</h2>
<p>The code in this tutorial should prove that you don&#x2019;t have to be a 100%-only POP or a 100%-only OOP developer. The two technologies not only can coexist, but they complement each other. It behooves you to be a flexible and open minded developer. I&#x2019;m so old &#x1F641; that I remember when OOP first debuted. There was <em>so much</em> resistance, but after several years went by, pretty much everyone jumped on the OOP bandwagon and, before we knew it, pretty much everything was in a class and/or class library. Recently, POP debuted and I feel like I&#x2019;m reliving the past. Some developers want to drop everything and rewrite all their code using protocols. Others want argue that POP is worthless. After using POP for several years, my gut instinct tells me that POP is here to stay and is very useful, but in no way does it totally devalue OOP. Both technologies have their advantages and disadvantages.</p>
<p>My advice is that you should be flexible and open-minded to new ideas with the caveat that there will always be flash-in-the-pan fads that come and go quickly. With experience, learning, and schooling, you&#x2019;ll learn to be able to tell the difference between fads and truly novel innovations.</p>
<p>The advent and adoption of OOP was a truly seminal event in programming history. So was the advent of POP. You should become fluent in both and use both.</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Design Patterns in Swift #3: Facade and Adapter]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>This tutorial is the third installment in our series on design patterns. I started<br>
this series with a tutorial examining two examples of patterns in the <a href="https://www.appcoda.com/design-pattern-creational/">&#x201C;creational&#x201D; category: <em>factory method</em> and <em>singleton</em></a>. I then discussed two examples of patterns in the <a href="https://www.appcoda.com/design-pattern-behavorial/">&#x201C;behavioral&#x201D; category: <em>observer</em> and <em>memento</em></a></p>]]></description><link>https://www.appcoda.com/design-pattern-structural/</link><guid isPermaLink="false">66612a0f166d3c03cf01147a</guid><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Tue, 04 Sep 2018 17:16:51 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2018/09/design-pattern-3-featured.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->
<img src="https://www.appcoda.com/content/images/wordpress/2018/09/design-pattern-3-featured.jpg" alt="Design Patterns in Swift #3: Facade and Adapter"><p>This tutorial is the third installment in our series on design patterns. I started<br>
this series with a tutorial examining two examples of patterns in the <a href="https://www.appcoda.com/design-pattern-creational/">&#x201C;creational&#x201D; category: <em>factory method</em> and <em>singleton</em></a>. I then discussed two examples of patterns in the <a href="https://www.appcoda.com/design-pattern-behavorial/">&#x201C;behavioral&#x201D; category: <em>observer</em> and <em>memento</em></a>.</p>
<p>In this tutorial, I&#x2019;ll explain two examples of patterns in the &#x201C;structural&#x201D; category: <em>facade</em> and <em>adapter</em>. I urge you to review my first two posts mentioned above so you can familiarize yourself with the concept of software design patterns. Beyond a brief reminder today of what constitutes a design pattern, I&#x2019;m not going to regurgitate all the definitions again. All the information you need to get up to speed is in my first two tutorials, <a href="https://www.appcoda.com/design-pattern-creational/">here</a> and <a href="https://www.appcoda.com/design-pattern-behavorial/">here</a>.</p>
<p>Let&#x2019;s briefly review some general definitions of design patterns here and in the next few sections. There are 23 classic software development design patterns probably first identified, collected, and explained all in one place by the &#x201C;Gang of Four&#x201D; (&#x201C;GoF&#x201D;), Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in their seminal book, <a href="https://smile.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8/?ref=appcoda.com">&#x201C;Design Patterns: Elements of Reusable Object-Oriented Software.&#x201D;</a>. Remember that today we&#x2019;ll focus on two of these patterns, <em>facade</em> and <em>adapter</em>, which fall into what the GoF calls the &#x201C;structural&#x201D; category.</p>
<h2>Protocol-oriented code with value semantics</h2>
<p>You&#x2019;ll still find that many tutorials about design patterns contain sample code based on object-oriented programming (OOP) principles, reference semantics, and <a href="http://iosbrain.com/blog/2018/06/07/swift-4-memory-management-via-arc-for-reference-types-classes/?ref=appcoda.com">reference types</a> (classes). I am endeavoring to create a series of tutorials on design patterns that are mostly based in <a href="https://www.appcoda.com/pop-vs-oop/">protocol-oriented programming</a> principles (POP), value semantics, and <a href="https://developer.apple.com/videos/play/wwdc2015/414/?ref=appcoda.com">value types</a> (structs). If you&#x2019;ve reviewed the first two articles in this series, I hope you followed my advice and familiarized yourselves with POP versus OOP and reference semantics versus value semantics. If not, I strongly encourage you to get up to speed on these topics. This tutorial is solely based in POP and value semantics.</p>
<h2>Design Patterns</h2>
<p>Design patterns are an extremely important tool with which developers can manage complexity. It&#x2019;s best to conceptualize them as generally templated techniques, each tailored to solving a corresponding, recurring, and readily identifiable problem. Look at them as a list of best practices you would use for coding scenarios that you see over and over again. To make this definition tangible, think of how many times you&#x2019;ve either used code or written code that conforms to <a href="https://www.appcoda.com/design-pattern-behavorial/">the observer design pattern</a>.</p>
<p>In observer, the subject instance, usually a single critical resource, broadcasts notifications about a change in its state to many observer instances that depend on that resource. Interested observers must tell the subject instance that they&#x2019;re interested in receiving notifications, in other words, they must subscribe to get notifications. Encoding iOS push notifications, where users must opt into receiving messages, is a great example of observer.</p>
<h3>Design pattern categories</h3>
<p>The GoF organized their 23 design patterns into three categories, <a href="https://www.appcoda.com/design-pattern-creational/">&#x201C;creational,&#x201D;</a> <a href="https://www.appcoda.com/design-pattern-behavorial/">&#x201C;behavioral,&#x201D;</a> and &#x201C;structural.&#x201D; This tutorial discusses two patterns in the <em>structural</em> category. Consider the word &#x201C;structure,&#x201D;</p>
<blockquote><p>
  &#x201C;something arranged in a definite pattern of organization&#x201D; and &#x201C;the aggregate of elements of an entity in their relationships to each other.&#x201D;</p>
<p>&#x2013; https://www.merriam-webster.com/dictionary/structure</p></blockquote>
<p>Structural design patterns are meant to help you to clearly define the purpose of a segment of code and clearly specify how other code interacts with that segment. Most patterns in this category enable you to simplify the use of your code. We can usually simplify use of code by creating an easily readable interface to that code. Since pieces/segments of code don&#x2019;t exist in a vacuum, providing a good interface to a code segment should obviously and cleanly define the possible relationships that can be built between that segment and other segments.</p>
<h2>The <em>facade</em> design pattern</h2>
<blockquote><p>
  The word &#x201C;facade&#x201D; is defined as &#x201C;any face of a building given special architectural treatment&#x201D; and &#x201C;a false, superficial, or artificial appearance or effect.&#x201D;</p>
<p>&#x2013; https://www.merriam-webster.com/dictionary/facade</p></blockquote>
<p>In most cases, we use the facade pattern to create one simple interface to a group of other, possibly many, and usually complex, interfaces. You have probably already created what are commonly called &#x201C;wrappers&#x201D; where you built a simple interface to a complex codebase with the purpose of simplifying the use of that codebase.</p>
<h3>Use case for <em>facade</em> design pattern app</h3>
<p>My facade example playground, available on <a href="https://github.com/appcoda/swift-design-patterns/tree/master/Facade?ref=appcoda.com">GitHub</a>, showcases how this pattern can create one simple interface to the sandboxed file system available to each iOS app. The iOS file system is a huge OS subsystem, allowing you to create, read, delete, move, rename, and copy files and directories; allowing you to get (and sometimes set) meta data about files and directories, e.g., list the files in a directory; allowing you to check the status of files/directories, e.g., determine if a file is writable; and, providing you with the names of predefined directories in which Apple prefers that you work. Note that you can do much more than what I just listed.</p>
<p>Since the iOS file system is such a grand topic with many different features and functions, it is an ideal candidate for using the facade design pattern to simplify its usage. A facade interface allows you to leave out functionality you don&#x2019;t need and that may clutter your code. Conversely, a facade interface allows you to specify only the functionality you need for a particular app, or in my case, to limit functionality to what I have found to be only the features I have used over time, and thus make my facade reusable, extensible, and maintainable for many of my apps.</p>
<p>I used protocol-oriented programming and value semantics for dividing and conquering major features of the iOS file system into reusable and extensible units: protocols and protocol extensions.</p>
<p>I then <a href="http://iosbrain.com/blog/2018/04/22/ios-file-management-with-filemanager-in-protocol-oriented-swift-4/?ref=appcoda.com"><em>composed</em> four protocols into one struct that represents a sandboxed iOS directory available to all iOS apps</a> (see also <a href="http://iosbrain.com/blog/2018/05/29/the-ios-file-system-in-depth/?ref=appcoda.com">here</a>). Since you&#x2019;re likely to run across the topics of POP and value semantics more and more, note that the terms <em>composed</em> and <em>composition</em> are synonymous herein.</p>
<p>Note that I left Swift error handling and more generic error checking out of the code shown below solely for didactic purposes, i.e., so you can more easily concentrate only on understanding use of the facade pattern.</p>
<h3>Sample code for the <em>facade</em> design pattern</h3>
<p>Let&#x2019;s walk through my code. Make sure you follow along with my code in the playground hosted on <a href="https://github.com/appcoda/swift-design-patterns/tree/master/Facade?ref=appcoda.com">GitHub</a>. Here&#x2019;s a list of predefined directories in which Apple prefers you do much of your iOS app&#x2019;s work:</p>
<pre class="swift">enum AppDirectories : String {
    case Documents = &quot;Documents&quot;
    case Inbox = &quot;Inbox&quot;
    case Library = &quot;Library&quot;
    case Temp = &quot;tmp&quot;
}
</pre>
<p>By constraining my file manipulation code to these known directories, I control complexity, simplify, and stay within the bounds of the Human Interface Guidelines.</p>
<p>Before looking at my core code for file manipulation, let&#x2019;s first look at my facade design pattern-based interface as that&#x2019;s the topic of this tutorial. I created the <code>iOSAppFileSystemDirectory</code> struct as a simple and readable interface to common file system features available for each of the directories specified in my <code>AppDirectories</code> enum. Yes, I could get involved with things like the <a href="https://developer.apple.com/documentation/foundation/filemanager/1414652-createsymboliclink?ref=appcoda.com">creation of symbolic links</a> or the use of fine grained manipulation of individual files using the <a href="https://developer.apple.com/documentation/foundation/filehandle?ref=appcoda.com"><code>FileHandle</code></a> class, but I almost never use these features, and <em>most importantly</em>, I&#x2019;m <em>deliberately</em> keeping things simple.</p>
<p>I&#x2019;ve created a facade composed of four protocols (I know you see three immediately below, but one of the protocols inherits from another):</p>
<pre class="swift">struct iOSAppFileSystemDirectory : AppFileManipulation, AppFileStatusChecking, AppFileSystemMetaData {
    
    let workingDirectory: AppDirectories

    init(using directory: AppDirectories) {
        self.workingDirectory = directory
    }

    func writeFile(containing text: String, withName name: String) -&gt; Bool {
        return writeFile(containing: text, to: workingDirectory, withName: name)
    }
    
    func readFile(withName name: String) -&gt; String {
        return readFile(at: workingDirectory, withName: name)
    }
    
    func deleteFile(withName name: String) -&gt; Bool {
        return deleteFile(at: workingDirectory, withName: name)
    }
    
    func showAttributes(forFile named: String) -&gt; Void {
        let fullPath = buildFullPath(forFileName: named, inDirectory: workingDirectory)
        let fileAttributes = attributes(ofFile: fullPath)
        for attribute in fileAttributes {
            print(attribute)
        }
    }
    
    func list() {
        list(directory: getURL(for: workingDirectory))
    }
    
} // end struct iOSAppFileSystemDirectory
</pre>
<p>Here&#x2019;s some code that tests my <code>iOSAppFileSystemDirectory</code> struct:</p>
<pre class="swift">var iOSDocumentsDirectory = iOSAppFileSystemDirectory(using: .Documents)

iOSDocumentsDirectory.writeFile(containing: &quot;New file created.&quot;, withName: &quot;myFile3.txt&quot;)
iOSDocumentsDirectory.list()
iOSDocumentsDirectory.readFile(withName: &quot;myFile3.txt&quot;)
iOSDocumentsDirectory.showAttributes(forFile: &quot;myFile3.txt&quot;)
iOSDocumentsDirectory.deleteFile(withName: &quot;myFile3.txt&quot;)
</pre>
<p>Here&#x2019;s the output to console from executing the previous code snippet in my playground:</p>
<pre class="swift">----------------------------
LISTING: /var/folders/5_/kd8__nv1139__dq_3nfvsmhh0000gp/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.Swift-Facade-Design-Pattern-1C4BD3E3-E23C-4991-A344-775D5585D1D7/Documents

File: &quot;myFile3.txt&quot;
File: &quot;Shared Playground Data&quot;

----------------------------

File created with contents: New file created.

(key: __C.FileAttributeKey(_rawValue: NSFileType), value: NSFileTypeRegular)
(key: __C.FileAttributeKey(_rawValue: NSFilePosixPermissions), value: 420)
(key: __C.FileAttributeKey(_rawValue: NSFileSystemNumber), value: 16777223)
(key: __C.FileAttributeKey(_rawValue: NSFileExtendedAttributes), value: {
    &quot;com.apple.quarantine&quot; = &lt;30303836 3b356238 36656364 373b5377 69667420 46616361 64652044 65736967 6e205061 74746572 6e3b&gt;;
})
(key: __C.FileAttributeKey(_rawValue: NSFileReferenceCount), value: 1)
(key: __C.FileAttributeKey(_rawValue: NSFileSystemFileNumber), value: 24946094)
(key: __C.FileAttributeKey(_rawValue: NSFileGroupOwnerAccountID), value: 20)
(key: __C.FileAttributeKey(_rawValue: NSFileModificationDate), value: 2018-08-29 18:58:31 +0000)
(key: __C.FileAttributeKey(_rawValue: NSFileCreationDate), value: 2018-08-29 18:58:31 +0000)
(key: __C.FileAttributeKey(_rawValue: NSFileSize), value: 17)
(key: __C.FileAttributeKey(_rawValue: NSFileExtensionHidden), value: 0)
(key: __C.FileAttributeKey(_rawValue: NSFileOwnerAccountID), value: 502)

File deleted.
</pre>
<p>Let&#x2019;s briefly discuss the protocols that were used to compose <code>iOSAppFileSystemDirectory</code>. Here we have the <code>AppDirectoryNames</code> protocol and protocol extension which compartmentalize the retrieval of full paths of type <code>URL</code> to the Apple-predefined directories as specified in my <code>AppDirectories</code> enum:</p>
<pre class="swift">protocol AppDirectoryNames {
    
    func documentsDirectoryURL() -&gt; URL
    
    func inboxDirectoryURL() -&gt; URL
    
    func libraryDirectoryURL() -&gt; URL
    
    func tempDirectoryURL() -&gt; URL
    
    func getURL(for directory: AppDirectories) -&gt; URL
    
    func buildFullPath(forFileName name: String, inDirectory directory: AppDirectories) -&gt; URL
    
} // end protocol AppDirectoryNames

extension AppDirectoryNames {
    
    func documentsDirectoryURL() -&gt; URL {
        return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    }
    
    func inboxDirectoryURL() -&gt; URL {
        return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(AppDirectories.Inbox.rawValue) // &quot;Inbox&quot;)
    }
    
    func libraryDirectoryURL() -&gt; URL {
        return FileManager.default.urls(for: FileManager.SearchPathDirectory.libraryDirectory, in: .userDomainMask).first!
    }
    
    func tempDirectoryURL() -&gt; URL {
        return FileManager.default.temporaryDirectory
        //urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(AppDirectories.Temp.rawValue) //&quot;tmp&quot;)
    }
    
    func getURL(for directory: AppDirectories) -&gt; URL {
        switch directory {
        case .Documents:
            return documentsDirectoryURL()
        case .Inbox:
            return inboxDirectoryURL()
        case .Library:
            return libraryDirectoryURL()
        case .Temp:
            return tempDirectoryURL()
        }
    }
    
    func buildFullPath(forFileName name: String, inDirectory directory: AppDirectories) -&gt; URL {
        return getURL(for: directory).appendingPathComponent(name)
    }
} // end extension AppDirectoryNames
</pre>
<p><code>AppFileStatusChecking</code> is my protocol and protocol extension that encapsulate getting state data about files stored in directories as specified in my <code>AppDirectories</code> enum. By &#x201C;state,&#x201D; I mean determining if a file exists, if it&#x2019;s writable, etc.</p>
<pre class="swift">protocol AppFileStatusChecking {
    func isWritable(file at: URL) -&gt; Bool
    
    func isReadable(file at: URL) -&gt; Bool
    
    func exists(file at: URL) -&gt; Bool
}

extension AppFileStatusChecking {
    func isWritable(file at: URL) -&gt; Bool {
        if FileManager.default.isWritableFile(atPath: at.path) {
            print(at.path)
            return true
        }
        else {
            print(at.path)
            return false
        }
    }
    
    func isReadable(file at: URL) -&gt; Bool {
        if FileManager.default.isReadableFile(atPath: at.path) {
            print(at.path)
            return true
        }
        else {
            print(at.path)
            return false
        }
    }
    
    func exists(file at: URL) -&gt; Bool {
        if FileManager.default.fileExists(atPath: at.path) {
            return true
        }
        else {
            return false
        }
    }
} // end extension AppFileStatusChecking
</pre>
<p><code>AppFileSystemMetaData</code> is my protocol and protocol extension that compartmentalize listing directory contents and getting extended file attributes, both from directories as specified in my <code>AppDirectories</code> enum:</p>
<pre class="swift">protocol AppFileSystemMetaData {
    func list(directory at: URL) -&gt; Bool
    
    func attributes(ofFile atFullPath: URL) -&gt; [FileAttributeKey : Any]
}

extension AppFileSystemMetaData
{
    func list(directory at: URL) -&gt; Bool {
        let listing = try! FileManager.default.contentsOfDirectory(atPath: at.path)
        
        if listing.count &gt; 0 {
            print(&quot;\n----------------------------&quot;)
            print(&quot;LISTING: \(at.path)&quot;)
            print(&quot;&quot;)
            for file in listing {
                print(&quot;File: \(file.debugDescription)&quot;)
            }
            print(&quot;&quot;)
            print(&quot;----------------------------\n&quot;)
            
            return true
        }
        else {
            return false
        }
    }
    
    func attributes(ofFile atFullPath: URL) -&gt; [FileAttributeKey : Any] {
        return try! FileManager.default.attributesOfItem(atPath: atFullPath.path)
    }
} // end extension AppFileSystemMetaData
</pre>
<p>Finally, the <code>AppFileManipulation</code> protocol and protocol extension encapsulate the reading, writing, deleting, renaming, moving, copying, and changing the file extension of files located in directories as specified in my <code>AppDirectories</code> enum:</p>
<pre class="swift">protocol AppFileManipulation : AppDirectoryNames {
    func writeFile(containing: String, to path: AppDirectories, withName name: String) -&gt; Bool
    
    func readFile(at path: AppDirectories, withName name: String) -&gt; String
    
    func deleteFile(at path: AppDirectories, withName name: String) -&gt; Bool
    
    func renameFile(at path: AppDirectories, with oldName: String, to newName: String) -&gt; Bool
    
    func moveFile(withName name: String, inDirectory: AppDirectories, toDirectory directory: AppDirectories) -&gt; Bool
    
    func copyFile(withName name: String, inDirectory: AppDirectories, toDirectory directory: AppDirectories) -&gt; Bool
    
    func changeFileExtension(withName name: String, inDirectory: AppDirectories, toNewExtension newExtension: String) -&gt; Bool
}

extension AppFileManipulation {
    func writeFile(containing: String, to path: AppDirectories, withName name: String) -&gt; Bool {
        let filePath = getURL(for: path).path + &quot;/&quot; + name
        let rawData: Data? = containing.data(using: .utf8)
        return FileManager.default.createFile(atPath: filePath, contents: rawData, attributes: nil)
    }
    
    func readFile(at path: AppDirectories, withName name: String) -&gt; String {
        let filePath = getURL(for: path).path + &quot;/&quot; + name
        let fileContents = FileManager.default.contents(atPath: filePath)
        let fileContentsAsString = String(bytes: fileContents!, encoding: .utf8)
        print(&quot;File created with contents: \(fileContentsAsString!)\n&quot;)
        return fileContentsAsString!
    }
    
    func deleteFile(at path: AppDirectories, withName name: String) -&gt; Bool {
        let filePath = buildFullPath(forFileName: name, inDirectory: path)
        try! FileManager.default.removeItem(at: filePath)
        print(&quot;\nFile deleted.\n&quot;)
        return true
    }
    
    func renameFile(at path: AppDirectories, with oldName: String, to newName: String) -&gt; Bool {
        let oldPath = getURL(for: path).appendingPathComponent(oldName)
        let newPath = getURL(for: path).appendingPathComponent(newName)
        try! FileManager.default.moveItem(at: oldPath, to: newPath)
        
        // highlights the limitations of using return values
        return true
    }
    
    func moveFile(withName name: String, inDirectory: AppDirectories, toDirectory directory: AppDirectories) -&gt; Bool {
        let originURL = buildFullPath(forFileName: name, inDirectory: inDirectory)
        let destinationURL = buildFullPath(forFileName: name, inDirectory: directory)
        // warning: constant &apos;success&apos; inferred to have type &apos;()&apos;, which may be unexpected
        // let success =
        try! FileManager.default.moveItem(at: originURL, to: destinationURL)
        return true
    }
    
    func copyFile(withName name: String, inDirectory: AppDirectories, toDirectory directory: AppDirectories) -&gt; Bool {
        let originURL = buildFullPath(forFileName: name, inDirectory: inDirectory)
        let destinationURL = buildFullPath(forFileName: name, inDirectory: directory)
        try! FileManager.default.copyItem(at: originURL, to: destinationURL)
        return true
    }
    
    func changeFileExtension(withName name: String, inDirectory: AppDirectories, toNewExtension newExtension: String) -&gt; Bool {
        var newFileName = NSString(string:name)
        newFileName = newFileName.deletingPathExtension as NSString
        newFileName = (newFileName.appendingPathExtension(newExtension) as NSString?)!
        let finalFileName:String =  String(newFileName)
        
        let originURL = buildFullPath(forFileName: name, inDirectory: inDirectory)
        let destinationURL = buildFullPath(forFileName: finalFileName, inDirectory: inDirectory)
        
        try! FileManager.default.moveItem(at: originURL, to: destinationURL)
        
        return true
    }
} // end extension AppFileManipulation
</pre>
<h2>The <em>adapter</em> design pattern</h2>
<blockquote><p>
  The word &#x201C;adapt&#x201D; is defined as &#x201C;to make fit (as for a new use) often by modification.&#x201D;</p>
<p>&#x2013; https://www.merriam-webster.com/dictionary/adapts</p></blockquote>
<blockquote><p>
  The word &#x201C;adapter&#x201D; is defined as &#x201C;an attachment for adapting apparatus for uses not originally intended.&#x201D;</p>
<p>&#x2013; https://www.merriam-webster.com/dictionary/adapter</p></blockquote>
<p>The adapter pattern is used so that an existing codebase (call it &#x201C;A&#x201D;) can work, without modifying the original &#x201C;A&#x201D; code, with other code (call it &#x201C;B&#x201D;) that may not be completely compatible with the existing, original codebase &#x201C;A.&#x201D; We can create some kind of <em>adapter</em> that allows &#x201C;A&#x201D; and &#x201C;B&#x201D; to work together despite their differences. Remember that the existing, original codebase &#x201C;A&#x201D; cannot be modified (either because it would break the code or because we don&#x2019;t have the source).</p>
<h3>Use case for <em>adapter</em> design pattern app</h3>
<p>My adapter example playground, available on <a href="https://github.com/appcoda/swift-design-patterns/tree/master/Adapter?ref=appcoda.com">GitHub</a>, showcases how we&#x2019;ll use the iOS file system as a substrate on which to discuss and design an example of the adapter pattern. Let&#x2019;s say we&#x2019;ve got my iOS file system code from the preceding sections up above where all paths to directories and files are expressed as <code>URL</code> instances. Consider a scenario in which we&#x2019;ve been given a huge chunk of code that also manipulates the iOS file system, but where all paths to directories and files are expressed as String path instances, and the URL-based code must be made to work with the String path-based code.</p>
<h3>Sample code for the <em>adapter</em> design pattern</h3>
<p>Let&#x2019;s walk through my code. Make sure you follow along with my code in the playground hosted on <a href="https://github.com/appcoda/swift-design-patterns/tree/master/Adapter?ref=appcoda.com">GitHub</a>. In order to concentrate solely on the adapter pattern, we&#x2019;ll use slimmed-down versions of my <code>AppDirectories</code> enum and <code>AppDirectoryNames</code> protocol and protocol extension:</p>
<pre class="swift">enum AppDirectories : String {
    case Documents = &quot;Documents&quot;
    case Temp = &quot;tmp&quot;
}

protocol AppDirectoryNames {
    func documentsDirectoryURL() -&gt; URL
    
    func tempDirectoryURL() -&gt; URL
}

extension AppDirectoryNames {
    func documentsDirectoryURL() -&gt; URL {
        return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    }
    
    func tempDirectoryURL() -&gt; URL {
        return FileManager.default.temporaryDirectory
    }
}
</pre>
<p>One technique we could use is to create a &#x201C;dedicated&#x201D; adapter, one which gives us string-based paths to directories as specified in <code>AppDirectories</code> and also gives us string-based paths to files stored in directories as specified in <code>AppDirectories</code>:</p>
<pre class="swift">// A dedicated adapter
struct iOSFile : AppDirectoryNames {
    let fileName: URL
    var fullPathInDocuments: String {
        return documentsDirectoryURL().appendingPathComponent(fileName.absoluteString).path
    }
    var fullPathInTemporary: String {
        return tempDirectoryURL().appendingPathComponent(fileName.absoluteString).path
    }
    var documentsStringPath: String {
        return documentsDirectoryURL().path
    }
    var temporaryStringPath: String {
        return tempDirectoryURL().path
    }

    init(fileName: String) {
        self.fileName = URL(string: fileName)!
    }
}
</pre>
<p>Here&#x2019;s some code that tests the <code>iOSFile</code> &#x201C;dedicated&#x201D; adapter &#x2014; and note my one inline comment:</p>
<pre class="swift">let iOSfile = iOSFile(fileName: &quot;myFile.txt&quot;)
iOSfile.fullPathInDocuments
iOSfile.documentsStringPath

iOSfile.fullPathInTemporary
iOSfile.temporaryStringPath

// We STILL have access to URLs
// through protocol AppDirectoryNames.
iOSfile.documentsDirectoryURL()
iOSfile.tempDirectoryURL()
</pre>
<p>Here are my playground&#x2019;s line-by-line annotations which appear to the right of each line of code, on the same line, representing runtime code values, corresponding to the previous code snippet &#x2014; the annotations below correspond one-to-one to the lines of code above:</p>
<pre class="swift">iOSFile
&quot;/var/folders/5_/kd8__nv1139__dq_3nfvsmhh0000gp/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.Swift-Adapter-Design-Pattern-0A71F81A-9388-41F5-ACBE-52A1A61A9B99/Documents/myFile.txt&quot;
&quot;/var/folders/5_/kd8__nv1139__dq_3nfvsmhh0000gp/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.Swift-Adapter-Design-Pattern-0A71F81A-9388-41F5-ACBE-52A1A61A9B99/Documents&quot;

&quot;/Users/softwaretesting/Library/Developer/XCPGDevices/52E1A81A-98AF-42DE-ADCF-E69AC8FA2791/data/Containers/Data/Application/F08EFF4F-8C4F-4BB7-B220-980E16344F18/tmp/myFile.txt&quot;
&quot;/Users/softwaretesting/Library/Developer/XCPGDevices/52E1A81A-98AF-42DE-ADCF-E69AC8FA2791/data/Containers/Data/Application/F08EFF4F-8C4F-4BB7-B220-980E16344F18/tmp&quot;

file:///var/folders/5_/kd8__nv1139__dq_3nfvsmhh0000gp/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.Swift-Adapter-Design-Pattern-0A71F81A-9388-41F5-ACBE-52A1A61A9B99/Documents/
file:///Users/softwaretesting/Library/Developer/XCPGDevices/52E1A81A-98AF-42DE-ADCF-E69AC8FA2791/data/Containers/Data/Application/F08EFF4F-8C4F-4BB7-B220-980E16344F18/tmp/
</pre>
<p>The technique I prefer is to design an adapter protocol that my string path-based code could adopt so that it could use <code>String</code> paths instead of <code>URL</code> paths.</p>
<pre class="swift">// Protocol-oriented approach
protocol AppDirectoryAndFileStringPathNamesAdpater : AppDirectoryNames {
    
    var fileName: String { get }
    var workingDirectory: AppDirectories { get }

    func documentsDirectoryStringPath() -&gt; String
    
    func tempDirectoryStringPath() -&gt; String
    
    func fullPath() -&gt; String
    
} // end protocol AppDirectoryAndFileStringPathAdpaterNames

extension AppDirectoryAndFileStringPathNamesAdpater {
   
    func documentsDirectoryStringPath() -&gt; String {
        return documentsDirectoryURL().path
    }
    
    func tempDirectoryStringPath() -&gt; String {
        return tempDirectoryURL().path
    }
    
    func fullPath() -&gt; String {
        switch workingDirectory {
        case .Documents:
            return documentsDirectoryStringPath() + &quot;/&quot; + fileName
        case .Temp:
            return tempDirectoryStringPath() + &quot;/&quot; + fileName
        }
    }

} // end extension AppDirectoryAndFileStringPathNamesAdpater

struct AppDirectoryAndFileStringPathNames : AppDirectoryAndFileStringPathNamesAdpater {
    
    let fileName: String
    let workingDirectory: AppDirectories
    
    init(fileName: String, workingDirectory: AppDirectories) {
        self.fileName = fileName
        self.workingDirectory = workingDirectory
    }
    
} // end struct AppDirectoryAndFileStringPathNames
</pre>
<p>Here&#x2019;s some code that tests my <code>AppDirectoryAndFileStringPathNames</code> struct, which adopts the <code>AppDirectoryAndFileStringPathNamesAdpater</code> adapter protocol (which is a descendent of the <code>AppDirectoryNames</code> protocol) &#x2014; and note my two inline comments:</p>
<pre class="swift">let appFileDocumentsDirectoryPaths = AppDirectoryAndFileStringPathNames(fileName: &quot;myFile.txt&quot;, workingDirectory: .Documents)
appFileDocumentsDirectoryPaths.fullPath()
appFileDocumentsDirectoryPaths.documentsDirectoryStringPath()

// We STILL have access to URLs
// through protocol AppDirectoryNames.
appFileDocumentsDirectoryPaths.documentsDirectoryURL()

let appFileTemporaryDirectoryPaths = AppDirectoryAndFileStringPathNames(fileName: &quot;tempFile.txt&quot;, workingDirectory: .Temp)
appFileTemporaryDirectoryPaths.fullPath()
appFileTemporaryDirectoryPaths.tempDirectoryStringPath()

// We STILL have access to URLs
// through protocol AppDirectoryNames.
appFileTemporaryDirectoryPaths.tempDirectoryURL()
</pre>
<p>Here are my playground&#x2019;s line-by-line annotations which appear to the right of each line of code, on the same line, representing runtime code values, corresponding to the previous code snippet &#x2014; the annotations below correspond one-to-one to the lines of code above:</p>
<pre class="swift">AppDirectoryAndFileStringPathNames
&quot;/var/folders/5_/kd8__nv1139__dq_3nfvsmhh0000gp/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.Swift-Adapter-Design-Pattern-A3DE7CC8-D60F-4448-869F-2A19556C62B2/Documents/myFile.txt&quot;
&quot;/var/folders/5_/kd8__nv1139__dq_3nfvsmhh0000gp/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.Swift-Adapter-Design-Pattern-A3DE7CC8-D60F-4448-869F-2A19556C62B2/Documents&quot;



file:///var/folders/5_/kd8__nv1139__dq_3nfvsmhh0000gp/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.Swift-Adapter-Design-Pattern-A3DE7CC8-D60F-4448-869F-2A19556C62B2/Documents/

AppDirectoryAndFileStringPathNames
&quot;/Users/softwaretesting/Library/Developer/XCPGDevices/52E1A81A-98AF-42DE-ADCF-E69AC8FA2791/data/Containers/Data/Application/CF3D4156-E773-4BC4-B117-E7BDEFA3F34C/tmp/tempFile.txt&quot;
&quot;/Users/softwaretesting/Library/Developer/XCPGDevices/52E1A81A-98AF-42DE-ADCF-E69AC8FA2791/data/Containers/Data/Application/CF3D4156-E773-4BC4-B117-E7BDEFA3F34C/tmp&quot;



file:///Users/softwaretesting/Library/Developer/XCPGDevices/52E1A81A-98AF-42DE-ADCF-E69AC8FA2791/data/Containers/Data/Application/CF3D4156-E773-4BC4-B117-E7BDEFA3F34C/tmp/
</pre>
<h2>Conclusion</h2>
<p>Not only do design patterns encourage code reuse, but can help you make your code consistent, readable, loosely coupled, and thus maintainable and extensible. When you identify recurring and generalized features in your apps, I encourage you to take your design pattern-based code and <a href="http://iosbrain.com/blog/2018/01/13/building-swift-4-frameworks-and-including-them-in-your-apps-xcode-9/?ref=appcoda.com">put it into frameworks</a> so you write it once and use it many more times.</p>
<p>Thanks for joining me again here on AppCoda. Enjoy your work, keep on learning, and I&#x2019;ll see you soon!</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Design Patterns in Swift #2: Observer and Memento]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>This tutorial is the second installment in an AppCoda series on design patterns <a href="https://www.appcoda.com/design-pattern-creational/">started last week</a>. There are 23 classic software development design patterns probably first identified,  collected, and explained all in one place by the &#x201C;Gang of Four&#x201D; (&#x201C;GoF&#x201D;), Erich Gamma, Richard Helm, Ralph Johnson,</p>]]></description><link>https://www.appcoda.com/design-pattern-behavorial/</link><guid isPermaLink="false">66612a0f166d3c03cf011476</guid><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Mon, 06 Aug 2018 00:43:39 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2018/08/michal-kubalczyk-505207-unsplash.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->
<img src="https://www.appcoda.com/content/images/wordpress/2018/08/michal-kubalczyk-505207-unsplash.jpg" alt="Design Patterns in Swift #2: Observer and Memento"><p>This tutorial is the second installment in an AppCoda series on design patterns <a href="https://www.appcoda.com/design-pattern-creational/">started last week</a>. There are 23 classic software development design patterns probably first identified,  collected, and explained all in one place by the &#x201C;Gang of Four&#x201D; (&#x201C;GoF&#x201D;), Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in their seminal book, <a href="https://smile.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8/?ref=appcoda.com">&#x201C;Design Patterns: Elements of Reusable Object-Oriented Software.&#x201D;</a>. Today, we&#x2019;ll focus on two of these patterns, &#x201C;observer&#x201D; and &#x201C;memento,&#x201D; which fall into what the GoF calls the &#x201C;behavioral&#x201D; category.</p>
<p>Software development is an endeavor into modeling real world scenarios in the hopes of creating tools to enhance the human experience in such scenarios. Tools for managing finances, e.g., banking apps and shopping aids like Amazon or eBay&#x2019;s iOS apps, definitely make life much simpler than it was for consumers just ten years ago. Think of how far we&#x2019;ve come. While software apps have generally gotten more powerful and simpler to use for consumers, development of said apps has gotten <a href="http://iosbrain.com/blog/2018/04/29/controlling-chaos-why-you-should-care-about-adding-error-checking-to-your-ios-apps/?ref=appcoda.com#chaos">much more complex</a> for developers.</p>
<p>So developers have created an arsenal of best practices to manage complexity, like object-oriented programming, protocol-oriented programming, value semantics, local reasoning, breaking large pieces of code into smaller ones with well-defined interfaces (like with Swift extensions), syntactic sugar, to name some of the most popular. One of the most important best practices that I didn&#x2019;t mention, but that merits much attention, is the use of design patterns.</p>
<h2>Design Patterns</h2>
<p>Design patterns are an extremely important tool with which developers can manage complexity. It&#x2019;s best to conceptualize them as generally templated techniques, each tailored to solving a corresponding, recurring, and readily identifiable problem. Look at them as a list of best practices you would use for coding scenarios that you see over and over again, like how to create objects from a related family of objects without having to understand all the gory implementation details of that family. The whole point of design patterns is that they apply to commonly occurring scenarios. They&#x2019;re reusable because they&#x2019;re generalized. A specific example should help.</p>
<p>Design patterns are not specific to some use case like iterating over a Swift array of 11 integers (<code>Int</code>). For example, the GoF defined the <em>iterator</em> pattern to provide a common interface for traversing through all items in some collection without knowing the intricacies (i.e., type) of the collection. A design pattern is not programming language code. It is a set of guidelines or rule of thumb for solving a common software scenario.</p>
<p>Remember that I discussed the <a href="https://www.appcoda.com/mvvm-vs-mvc/">&#x201C;Model-View-ViewModel&#x201D; or &#x201C;MVVM&#x201D;</a> design pattern here on AppCoda &#x2014; and of course the very well-known <a href="https://www.appcoda.com/mvvm-vs-mvc/">&#x201C;Model-View-Controller&#x201D; or &#x201C;MVC&#x201D;</a> design pattern, long favored by Apple and many iOS developers.</p>
<p>These two patterns are generally applied to <em>entire applications</em>. MVVM and MVC are <em>architectural</em> design patterns and are meant to separate the user interface (UI) from the app&#x2019;s data and from code for presentation logic, and to separate the app&#x2019;s data from core data processing and/or business logic. The GoF design patterns are more specific in nature, meant to solve more distinct problems <em>inside</em> an application&#x2019;s code base. You may use three or seven or even twelve GoF design patterns in one app. Remember my <em>iterator</em> example. Delegation is <a href="https://www.appcoda.com/swift-delegate/">another great example</a> of a design pattern, though not specifically on the GoF&#x2019;s list of 23.</p>
<p>While the GoF book has taken on biblical connotations for many developers, it is not without its detractors. We&#x2019;ll talk about that in the conclusion to this article.</p>
<h3>Design pattern categories</h3>
<p>The GoF organized their 23 design patterns into 3 categories, &#x201C;creational,&#x201D; &#x201C;structural,&#x201D; and &#x201C;behavioral.&#x201D; This tutorial discusses two patterns in the <em>behavioral</em> category. This  pattern&#x2019;s purpose is imposing safe, common sense, and consistent etiquette, form, and best practices for behaviour onto classes and structs (actors). We want good, consistent, and predictable behavior from all actors inside an entire application. We want good behavior both within actors themselves and between different actors that interact/communicate. Evaluation of actors&#x2019; behavior should be considered before and at compile time, which I sometimes call &#x201C;design time,&#x201D; <em>and</em> at runtime, when we&#x2019;ll have lots of <em>instances</em> of classes and structs all doing their own thing <em>and</em> constantly interacting/communicating. Since communication between instances leads to so much software complexity, having rules for consistent, efficient, and safe communications is of paramount importance, but that concept should not in any way diminish the need for good design practices when building each individual actor. Since we&#x2019;re so focused on behavior, we must remember to use consistent patterns when assigning responsibilities to actors and when assigning responsibilities to combinations of actors.</p>
<p>Before I wax too far theoretical, let me provide tangible examples to assure you that I&#x2019;ll be demonstrating theory with in-depth practice as realized in Swift code. In this tutorial, we&#x2019;ll see how to consistently assign responsibility for maintaining an actor&#x2019;s state. We&#x2019;ll also see how to consistently assign responsibility for one actor, the subject, to send notifications to many actor-observers, and conversely, how to consistently assign responsibility to the observers for registering with the subject to get notifications.</p>
<p>The whole notion of <em>consistency</em> should be self-evident to you when discussing design <em>patterns</em>. Keep in mind a theme that was highlighted in <a href="https://www.appcoda.com/design-pattern-creational/">last week&#x2019;s post</a>, a theme that will occur over and over as we discuss more and more design patterns: <a href="http://iosbrain.com/blog/2017/02/26/intro-to-object-oriented-principles-in-swift-3-via-a-message-box-class-hierarchy/?ref=appcoda.com#advantages">hiding complexity (encapsulation)</a>. It is one the highest goals of smart developers. For example, object-oriented (OOP) classes can provide very complex, sophisticated, and powerful functionality without requiring the developer to know anything about the internal workings of those classes. In the same vein, Swift <a href="https://www.appcoda.com/pop-vs-oop/">protocol-oriented programming</a> is an extremely important yet relatively new technique for controlling complexity. Managing <a href="http://iosbrain.com/blog/2018/01/02/understanding-swift-4-generics-and-applying-them-to-your-code/?ref=appcoda.com#complexity">complexity</a> is a developer&#x2019;s greatest burden, but here we are talking about taming that beast!</p>
<h3>A note on this tutorial&#x2019;s prose and definitions</h3>
<p>For this tutorial, I&#x2019;ve decided to concentrate my explanatory prose as inline commentary in my sample apps&#x2019; code. While I will provide brief explanations of today&#x2019;s design pattern concepts, I very much want you to look at my code, read the comments, and fully internalize the techniques I&#x2019;m sharing with you. After all, if you can&#x2019;t write the code, and can only talk about the code, you&#x2019;re not going to make it through very many job interviews &#x2014; and you&#x2019;re not really a hardcore developer.</p>
<p>You probably noticed in my definition of the behavioral design pattern that I&#x2019;m following Apple&#x2019;s <a href="https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html?ref=appcoda.com">documentation convention</a>:</p>
<blockquote><p>
  An instance of a class is traditionally known as an object. However, Swift structures and classes are much closer in functionality than in other languages, and much of this chapter describes functionality that applies to instances of <em>either</em> a class or a structure type. Because of this, the more general term instance is used.
</p></blockquote>
<p>I&#x2019;ve also taken the liberty of referring to classes and structs as &#x201C;actors&#x201D; at design time.</p>
<h2>The observer design pattern</h2>
<p>The observer pattern is probably something you&#x2019;ve all experienced while using Apple mobile devices, but hopefully you&#x2019;ve also noticed it while coding your iOS apps. Every time it rains where I live, I and a whole lot of other people around here get push notifications which pop up on our iPhones &#x2014; lock screen or normal screen &#x2014; whenever it rains. Here&#x2019;s what they look like:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification.png" alt="Design Patterns in Swift #2: Observer and Memento" width="1240" height="422" class="aligncenter size-full wp-image-13821" srcset="https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification.png 1240w, https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification-200x68.png 200w, https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification-600x204.png 600w, https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification-768x261.png 768w, https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification-1024x348.png 1024w, https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification-860x293.png 860w, https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification-680x231.png 680w, https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification-400x136.png 400w, https://www.appcoda.com/content/images/wordpress/2018/08/PushNotification-50x17.png 50w" sizes="(max-width: 1240px) 100vw, 1240px"></p>
<p><em>One source</em>, Apple, is sending out &#x2014; broadcasting &#x2014; notifications to <em>many</em> thousands of iPhones, on behalf of the National Weather Service, warning people in my area of the possibility of flooding. In more concrete terms, like at the level of an iOS app, one instance, the <em>subject</em>, notifies (many) other instances, the <em>observers</em>, of changes to the state of the <em>subject</em>. The instances participating in this broadcast type communication don&#x2019;t need to know about one another. This is a great example of <a href="https://www.webopedia.com/TERM/L/loose_coupling.html?ref=appcoda.com">loose coupling</a>.</p>
<p>The subject instance, usually a single critical resource, broadcasts notifications about a change in its state to many observer instances that depend on that resource. Interested observers must subscribe to get notifications.</p>
<p>Thankfully, iOS has a built-in and well-known feature for enabling the observer pattern: <a href="https://developer.apple.com/documentation/foundation/notificationcenter?ref=appcoda.com">NotificationCenter</a>, which I&#x2019;ll let you study up on yourself <a href="http://iosbrain.com/blog/2018/02/09/nsnotificationcenter-in-swift-4-intra-app-communication-sending-receiving-listening-stop-listening-for-messages/?ref=appcoda.com">here</a>.</p>
<h3>Use case for observer design pattern app</h3>
<p>My observer example project, available on <a href="https://github.com/appcoda/Observer-Pattern-Swift?ref=appcoda.com">GitHub</a>, showcases how this broadcast type communication works.</p>
<p>I know this is not quite how the iOS Human Interface Guidelines advise you to do things, but bear with me as I needed an example of a single critical resource. Suppose we were to take a proactive approach and have a single instance of a subject responsible for monitoring network connectivity/reachability. This is the broadcaster, and to implement one, you just need to have an actor adopt my <code>ObservedProtocol</code>.</p>
<p>Suppose there are multiple instances of observers, like an image downloader class, a login instance that verifies user credentials via a REST API, and an in-app browser that all subscribe to the subject to get notified of network connection status. To implement these, you could take pretty much any class and make it a descendent of my &#x201C;abstract&#x201D; <code>Observer</code> class, which adopts the <code>ObserverProtocol</code>. (I&#x2019;ll explain later why I limited my example observer code to a class.)</p>
<p>To implement observers for the purposes of my example app, I created the <code>NetworkConnectionHandler</code> class. When instances of this concrete class get notifications of <code>NetworkConnectionStatus.connected</code>, they turn a <code>UIView</code> instance green; when they   get notifications of <code>NetworkConnectionStatus.disconnected</code>, they turn a <code>UIView</code> instance red.</p>
<p>Here&#x2019;s my sample app code compiled, installed, and running on an iPhone 8 Plus:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/08/ObserverAppDemo.gif" alt="Design Patterns in Swift #2: Observer and Memento" width="338" height="598" class="aligncenter size-full wp-image-13820"></p>
<p>Here&#x2019;s the Xcode console output corresponding to the previous video:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/08/ObserverAppConsoleOutput.gif" alt="Design Patterns in Swift #2: Observer and Memento" width="562" height="230" class="aligncenter size-full wp-image-13819"></p>
<h3>Sample code for observer design pattern app</h3>
<p>To see the heavily commented code I just described in the previous section, please look at file <code>Observable.swift</code> in my sample project:</p>
<pre class="swift">
import Foundation

import UIKit

// Make notification names consistent and avoid stringly-typing.
// Try to use constants instead of strings or numbers.
extension Notification.Name {
    
    static let networkConnection = Notification.Name(&quot;networkConnection&quot;)
    static let batteryStatus = Notification.Name(&quot;batteryStatus&quot;)
    static let locationChange = Notification.Name(&quot;locationChange&quot;)

}

// Various network connection states -- made consistent.
enum NetworkConnectionStatus: String {
    
    case connected
    case disconnected
    case connecting
    case disconnecting
    case error
    
}

// The key to the notification&apos;s &quot;userInfo&quot; dictionary.
enum StatusKey: String {
    case networkStatusKey
}

// This protocol forms the basic design for OBSERVERS,
// entities whose operation CRTICIALLY depends
// on the status of some other, usually single, entity.
// Adopters of this protocol SUBSCRIBE to and RECEIVE
// notifications about that critical entity/resource.
protocol ObserverProtocol {
    
    var statusValue: String { get set }
    var statusKey: String { get }
    var notificationOfInterest: Notification.Name { get }
    func subscribe()
    func unsubscribe()
    func handleNotification()
    
}

// This template class abstracts out all the details
// necessary for an entity to SUBSCRIBE to and RECEIVE
// notifications about a critical entity/resource.
// It provides a &quot;hook&quot; (handleNotification()) in which
// subclasses of this base class can pretty much do whatever
// they need to do when specific notifications are received.
// This is basically an &quot;abstract&quot; class, not detectable
// at compile time, but I felt this was an exceptional case.
class Observer: ObserverProtocol {
    
    // This specific state reported by &quot;notificationOfInterest.&quot;
    // I use String for maximum portability. Yeah, yeah...
    // stringly-typed...
    var statusValue: String
    // The key to the notification&apos;s &quot;userInfo&quot; dictionary, with
    // which we can read the specific state and store in &quot;statusValue.&quot;
    // I use String for maximum portability. Yeah, yeah...
    // stringly-typed...
    let statusKey: String
    // The name of the notification this class has registered
    // to receive whenever messages are broadcast.
    let notificationOfInterest: Notification.Name
    
    // Initializer which registers/subscribes/listens for a specific
    // notification and then watches for a specific state as reported
    // by notifications when received.
    init(statusKey: StatusKey, notification: Notification.Name) {
        
        self.statusValue = &quot;N/A&quot;
        self.statusKey = statusKey.rawValue
        self.notificationOfInterest = notification
        
        subscribe()
    }
    
    // We&apos;re registering self (this) with NotificationCenter to receive
    // all notifications with the name stored in &quot;notificationOfInterest.&quot;
    // Whenever one of those notifications is received, the
    // &quot;receiveNotification(_:)&quot; method is called.
    func subscribe() {
        NotificationCenter.default.addObserver(self, selector: #selector(receiveNotification(_:)), name: notificationOfInterest, object: nil)
    }
    
    // It&apos;s a good idea to un-register from notifications when we no
    // longer need to listen, but this is more of a historic curiosity
    // as, since iOS 9.0, the OS does some type of cleanup.
    func unsubscribe() {
        NotificationCenter.default.removeObserver(self, name: notificationOfInterest, object: nil)
    }
    
    // Called whenever a message labelled &quot;notificationOfInterest&quot;
    // is received. This is our chance to do something when the
    // state of that critical resource we&apos;re observing changes.
    // This method &quot;must have one and only one argument (an instance
    // of NSNotification).&quot;
    @objc func receiveNotification(_ notification: Notification) {
        
        if let userInfo = notification.userInfo, let status = userInfo[statusKey] as? String {
            
            statusValue = status
            handleNotification()
            
            print(&quot;Notification \(notification.name) received; status: \(status)&quot;)
            
        }
        
    } // end func receiveNotification
    
    // YOU MUST OVERRIDE THIS METHOD; YOU MUST SUBCLASS THIS CLASS.
    // I&apos;ve MacGyvered this class into being &quot;abstract&quot; so you
    // can subclass and specialize as much as you want and not
    // have to worry about NotificationCenter details.
    func handleNotification() {
        fatalError(&quot;ERROR: You must override the [handleNotification] method.&quot;)
    }
    
    // Be kind and stop tapping a resource (NotificationCenter)
    // when we don&apos;t need to anymore.
    deinit {
        print(&quot;Observer unsubscribing from notifications.&quot;)
        unsubscribe()
    }
    
} // end class Observer

// An example of an observer, usually one of several
// (many?) that are all listening for notifications
// from some usually single critical resource. Notice that
// it&apos;s brief and can serve as a model for creating
// handlers for all sorts of notifications.
class NetworkConnectionHandler: Observer {
    
    var view: UIView
    
    // As long as you call &quot;super.init&quot; with valid
    // NotificationCenter-compatible values, you can
    // create whatever type of initializer you want.
    init(view: UIView) {
        
        self.view = view
        
        super.init(statusKey: .networkStatusKey, notification: .networkConnection)
    }
    
    // YOU MUST OVERRIDE THIS METHOD, but that
    // gives you the chance to handle notifications
    // in whatever way you deem fit.
    override func handleNotification() {
        
        if statusValue == NetworkConnectionStatus.connected.rawValue {
            view.backgroundColor = UIColor.green
        }
        else {
            view.backgroundColor = UIColor.red
        }
        
    } // end func handleNotification()
    
} // end class NetworkConnectionHandler

// An template for a subject, usually a single
// critical resource, that broadcasts notifications
// about a change in its state to many
// subscribers that depend on that resource.
protocol ObservedProtocol {
    var statusKey: StatusKey { get }
    var notification: Notification.Name { get }
    func notifyObservers(about changeTo: String) -&gt; Void
}

// When an adopter of this ObservedProtocol
// changes status, it notifies ALL subsribed
// observers. It BROADCASTS to ALL SUBSCRIBERS.
extension ObservedProtocol {

    func notifyObservers(about changeTo: String) -&gt; Void {
       NotificationCenter.default.post(name: notification, object: self, userInfo: [statusKey.rawValue : changeTo])
    }
    
} // end extension ObservedProtocol
</pre>
<p>I had intended to put most of the observer&#x2019;s notification handling logic into an extension of <code>ObserverProtocol</code> but ran into <code>@objc</code> when setting my <code>#selector</code>, then thought about using the block-based version of  <a href="https://developer.apple.com/documentation/foundation/notificationcenter/1411723-addobserver?ref=appcoda.com"><code>addObserver(forName:object:queue:using:)</code></a>, then passing in a notification handler closure, blah, blah, blah&#x2026; I decided that my notification handling code would be much more intelligible and educational as an abstract class.</p>
<p>I also realize that Swift has no formal concept of an abstract class, but you probably already know there is a commonly used workaround for creating one. So, again, to simplify my didactic goal of explaining the observer pattern, I made the <code>Observer</code> class &#x201C;abstract&#x201D; by forcing you to override its <code>handleNotification()</code> method. By doing so, I gave you the opportunity to inject <em>any</em> type of specialized logic you want to have executed whenever your <code>Observer</code> subclass instance receives a notification.</p>
<p>Shown immediately below is my sample project&#x2019;s <code>ViewController.swift</code> file, which shows you how to make use of my core logic in <code>Observable.swift</code>, which we just discussed and reviewed:</p>
<pre class="swift">
import UIKit

// By adopting the ObservedProtocol, this view controller
// gains the capability for broadcasting notifications via
// NotificationCenter to ANY entities throughout this
// WHOLE APP whom are interested in receiving those notifications.
// Notice how little this class needs to do to gain
// notification capability?
class ViewController: UIViewController, ObservedProtocol {
    
    @IBOutlet weak var topBox: UIView!
    @IBOutlet weak var middleBox: UIView!
    @IBOutlet weak var bottomBox: UIView!
    
    // Mock up three entities whom are dependent upon a
    // critical resource: network connectivity. They need
    // to observe the status of the critical resource.
    var networkConnectionHandler0: NetworkConnectionHandler?
    var networkConnectionHandler1: NetworkConnectionHandler?
    var networkConnectionHandler2: NetworkConnectionHandler?
    
    // ObservedProtocol conformance -- two properties.
    let statusKey: StatusKey = StatusKey.networkStatusKey
    let notification: Notification.Name = .networkConnection
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        // Here are three entities now listening for notifications
        // from the enclosing ViewController class.
        networkConnectionHandler0 = NetworkConnectionHandler(view: topBox)
        networkConnectionHandler1 = NetworkConnectionHandler(view: middleBox)
        networkConnectionHandler2 = NetworkConnectionHandler(view: bottomBox)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // Mock up a critical resource whose state can change.
    // I&apos;m pretending that this ViewController is
    // responsible for network reachability/connectivity.
    // When we have a network connection, all interested
    // listeners are informed. When network access is lost,
    // all interested listeners are informed.
    @IBAction func switchChanged(_ sender: Any) {
        
        let swtich:UISwitch = sender as! UISwitch
        
        if swtich.isOn {
            notifyObservers(about: NetworkConnectionStatus.connected.rawValue)
        }
        else {
            notifyObservers(about: NetworkConnectionStatus.disconnected.rawValue)
        }
        
    } // end func switchChanged
    
} // end class ViewController
</pre>
<h2>The <em>memento</em> design pattern</h2>
<p>Most iOS developers are familiar with the memento pattern. Think of iOS facilities for <a href="https://developer.apple.com/documentation/foundation/archives_and_serialization?ref=appcoda.com">archives and serialization</a> which allow you to &#x201C;Convert objects and values to and from property list, JSON, and other flat binary representations.&#x201D; Think of the iOS <a href="https://developer.apple.com/documentation/uikit/view_controllers/preserving_your_app_s_ui_across_launches?ref=appcoda.com">state preservation and restoration</a> feature, which remembers and then returns &#x201C;your app to its previous state after it is terminated by the system.&#x201D;</p>
<p>The memento design pattern is meant to capture, represent, and store the internal state of an instance at a specific point in time and then allow you to find that instance&#x2019;s state representation at a later time and restore it. When you restore the state of an instance, it should exactly reflect it&#x2019;s state at the time of capture. While this may sound obvious, you should ensure that all instance property access levels should be respected during capture and restoration, e.g., <code>public</code> data should be restored to <code>public</code> properties and <code>private</code> data should be restored to <code>private</code> properties.</p>
<p>To keep things simple, I used iOS&#x2019;s <a href="https://developer.apple.com/documentation/foundation/userdefaults?ref=appcoda.com"><code>UserDefaults</code></a> as the core of my instance state storage and recovery process.</p>
<h3>Use case for memento design pattern app</h3>
<p>While I understand that iOS already has facilities for archiving and serialization, I developed sample code that can save and recover an class&#x2019;s state. My code does a pretty good job of abstracting archiving and de-archiving so that you can store and recover the state of a variety of different instances with varying properties. But my example is not meant for production use. It is a didactic example formulated to explain the memento pattern.</p>
<p>My memento example project, available on <a href="https://github.com/appcoda/Memento-Pattern-Swift?ref=appcoda.com">GitHub</a>, showcases how a <code>User</code> class instance&#x2019;s state, with <code>firstName</code>, <code>lastName</code>, and <code>age</code> properties, can be persisted to  <code>UserDefaults</code> and then later recovered. At first, no <code>User</code> instance is available to recover, but then I enter one, archive it, and then recover it, as shown here:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/08/MementoDemoApp.gif" alt="Design Patterns in Swift #2: Observer and Memento" width="338" height="598" class="aligncenter size-full wp-image-13818"></p>
<p>Here&#x2019;s the console output corresponding to the previous video:</p>
<pre class="swift">
Empty entity.

lastName: Adams
age: 87
firstName: John

lastName: Adams
age: 87
firstName: John
</pre>
<h3>Sample code for memento design pattern app</h3>
<p>My memento code is straightforward. It provides the <code>Memento</code> protocol and protocol extension for handling and abstracting all the details of gross archiving and de-archiving of the member properties of classes that adopt the <code>Memento</code> protocol. The extension also allows you to print the entire state of an instance to console at any given point in time. I used a <code>Dictionary&lt;String, String&gt;</code> to store an adopting class&#x2019;s property names as keys and property contents as values. I stored values as <code>String</code> to keep my implementation simple and easily understood, fully well acknowledging that there are many use cases which would require you to archive and de-archive much more complex property types. This is a tutorial about <em>design patterns</em>, not a code base for a production app.</p>
<p>Notice that I added <code>persist()</code> and <code>recover()</code> methods to the <code>Memento</code> protocol, which <em>must</em> be implemented by any class that adopts the <code>Memento</code> protocol. These methods provide developers with the opportunity to archive and de-archive <code>Memento</code> protocol-adopting class&#x2019;s <em>specific</em> properties, <em>by name</em>. In other words, the elements of the <code>state</code> property of type <code>Dictionary&lt;String, String&gt;</code> can be matched one-to-one with the <code>Memento</code> protocol-adopting class&#x2019;s properties. Each property name corresponds to a dictionary element key and each property value corresponds to the dictionary element&#x2019;s value which matches said key. Just look at the code and you&#x2019;ll understand.</p>
<p>Since the <code>persist()</code> and <code>recover()</code> methods <em>must</em> be implemented by any class that adopts the <code>Memento</code> protocol, properties of all access levels, e.g., <code>public</code>, <code>private</code>, and <code>fileprivate</code> are visible to, and accessible by, these methods.</p>
<p>You may wonder why I made the <code>Memento</code> protocol class-only. I did so because of that horrible Swift compiler message, &#x201C;Cannot use mutating member on immutable value: &#x2018;self&#x2019; is immutable.&#x201D; Discussing it is way beyond the scope of this tutorial, but if you&#x2019;d like to torture yourself, read a great description of the issue <a href="https://www.bignerdranch.com/blog/protocol-oriented-problems-and-the-immutable-self-error/?ref=appcoda.com">here</a>.</p>
<p>Here&#x2019;s my core logic for implementing the memento design pattern, found in file <code>Memento.swift</code> of my sample app:</p>
<pre class="swift">
import Foundation

// I&apos;ve only limited this protocol to reference types because of the
// &quot;Cannot use mutating member on immutable value: &#x2018;self&#x2019; is immutable&quot;
// conundrum.
protocol Memento : class {
    
    // Key for accessing the &quot;state&quot; property
    // from UserDefaults.
    var stateName: String { get }
    
    // Current state of adopting class -- all
    // property names (keys) and property values.
    var state: Dictionary<string, string> { get set }
    
    // Save &quot;state&quot; property with key as specified
    // in &quot;stateName&quot; into UserDefaults (&quot;generic&quot; save).
    func save()
    
    // Retrieve &quot;state&quot; property using key as specified
    // in &quot;stateName&quot; from UserDefaults (&quot;generic&quot; restore).
    func restore()
    
    // Customized, &quot;specific&quot; save of &quot;state&quot; dictionary with
    // keys corresponding to member properties of adopting
    // class, and save of each property value (class-specific).
    func persist()
    
    // Customized, &quot;specific&quot; retrieval of &quot;state&quot; dictionary using
    // keys corresponding to member properties of adopting
    // class, and retrieval of each property value  (class-specific).
    func recover()
    
    // Print all adopting class&apos;s member properties by
    // traversing &quot;state&quot; dictionary, so output is of
    // format:
    //
    // Property 1 name (key): property 1 value
    // Property 2 name (key): property 2 value ...
    func show()
    
} // end protocol Memento

extension Memento {
    
    // Save state into dictionary archived on disk.
    func save() {
        UserDefaults.standard.set(state, forKey: stateName)
    }
    
    // Read state into dictionary archived on disk.
    func restore() {
        
        if let dictionary = UserDefaults.standard.object(forKey: stateName) as! Dictionary<string, string>? {
            state = dictionary
        }
        else {
            state.removeAll()
        }
        
    } // end func restore()
    
    // Storing state in dictionary makes display
    // of object state so easy and intuitive.
    func show() {
        
        var line = &quot;&quot;
        
        if state.count &gt; 0 {
            
            for (key, value) in state {
                line += key + &quot;: &quot; + value + &quot;\n&quot;
            }
            
            print(line)
            
        }
        
        else {
            print(&quot;Empty entity.\n&quot;)
        }
            
    } // end func show()
    
} // end extension Memento

// By adopting the Memento protocol, we can, with relative
// ease, save the state of an entire class to persistant
// storage and then retrieve that state at a later time, i.e.,
// across different instances of this app running.
class User: Memento {
    
    // These two properties are required by Memento.
    let stateName: String
    var state: Dictionary<string, string>
    
    // These properties are specific to a class that
    // represents some kind of system user account.
    var firstName: String
    var lastName: String
    var age: String
    
    // Initializer for persisting a new user to disk, or for
    // updating an existing user. The key value used for accessing
    // persistent storage is property &quot;stateName.&quot;
    init(firstName: String, lastName: String, age: String, stateName: String) {
        
        self.firstName = firstName
        self.lastName = lastName
        self.age = age
        
        self.stateName = stateName
        self.state = Dictionary<string, string>()
        
        persist()
        
    } // end init(firstName...
    
    // Initializer for retrieving a user from disk, if one
    // exists. The key value used for retrieving state from
    // persistent storage is property &quot;stateName.&quot;
    init(stateName: String) {
        
        self.stateName = stateName
        self.state = Dictionary<string, string>()
        
        self.firstName = &quot;&quot;
        self.lastName = &quot;&quot;
        self.age = &quot;&quot;
        
        recover()
        
    } // end init(stateName...

    // Save the user&apos;s properties to persistent storage.
    // We intuitively save each property value by making
    // the keys in the dictionary correspond one-to-one with
    // this class&apos;s property names.
    func persist() {
        
        state[&quot;firstName&quot;] = firstName
        state[&quot;lastName&quot;] = lastName
        state[&quot;age&quot;] = age
        
        save() // leverage protocol extension
        
    } // end func persist()
    
    // Read existing user&apos;s properties from persistent storage.
    // After retrieving the &quot;state&quot; dictionary from UserDefaults,
    // we easily restore each property value because
    // the keys in the dictionary correspond one-to-one with
    // this class&apos;s property names.
    func recover() {
        
        restore() // leverage protocol extension
            
        if state.count &gt; 0 {
            firstName = state[&quot;firstName&quot;]!
            lastName = state[&quot;lastName&quot;]!
            age = state[&quot;age&quot;]!
        }
        else {
            self.firstName = &quot;&quot;
            self.lastName = &quot;&quot;
            self.age = &quot;&quot;
        }
        
    } // end func recover
    
} // end class User
</string,></string,></string,></string,></string,></pre>
<p>Here&#x2019;s the code for implementing the memento design pattern use case I described earlier (archiving and de-archiving an instance of class <code>User</code>), as found in my sample app as file <code>ViewController.swift</code>:</p>
<pre class="swift">
import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var firstNameTextField: UITextField!
    @IBOutlet weak var lastNameTextField: UITextField!
    @IBOutlet weak var ageTextField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // Called when &quot;Save User&quot; button is tapped. Stores
    // &quot;User&quot; class instance properties to UserDefaults
    // based on stateName property value of &quot;userKey&quot; (but
    // use whatever lights your fire).
    @IBAction func saveUserTapped(_ sender: Any) {
        
        if firstNameTextField.text != &quot;&quot; &amp;&amp;
            lastNameTextField.text != &quot;&quot; &amp;&amp;
            ageTextField.text != &quot;&quot; {
            
            let user = User(firstName: firstNameTextField.text!,
                            lastName: lastNameTextField.text!,
                            age: ageTextField.text!,
                            stateName: &quot;userKey&quot;)
            user.show()
            
        }
        
    } // end func saveUserTapped
    
    // Called when &quot;Restore User&quot; button is tapped. Retrieves
    // &quot;User&quot; class instance properties from UserDefaults
    // based on stateName property value of &quot;userKey,&quot; if
    // a key/value pair with key &quot;userKey&quot; exists.
    @IBAction func restoreUserTapped(_ sender: Any) {
        
        let user = User(stateName: &quot;userKey&quot;)
        firstNameTextField.text = user.firstName
        lastNameTextField.text = user.lastName
        ageTextField.text = user.age
        user.show()

    }
    
} // end class ViewController
</pre>
<h2>Conclusion</h2>
<p>Some critics have claimed that use of design patterns is proof of deficiencies in programming languages and that seeing recurring patterns in code is a bad thing. I disagree. Expecting a language to have a feature for <em>everything</em> is silly and would most likely lead to enormous languages like C++ into becoming even larger and more complex and thus harder to learn, use, and maintain. Recognizing and solving recurring problems is a positive human trait worthy of positive reinforcement. Design patterns are successful examples of learning from history, something humankind has failed to do too many times. Coming up with abstract and standardized solutions to common problems makes those solutions portable and more likely to be distributed.</p>
<p>A combination of a compact language like Swift and an arsenal of best practices, like design patterns, is an ideal and happy medium. Consistent code is generally readable and maintainable code. Remember too that design patterns are ever-evolving as millions of developers are constantly discussing and sharing ideas. By virtue of being linked together over the World Wide Web, this developer discussion has lead to constantly self-regulating collective intelligence.</p>

<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Design Patterns in Swift #1: Factory Method and Singleton]]></title><description><![CDATA[<!--kg-card-begin: html-->
<p>There are 23 classic software development design patterns probably first identified,  collected, and explained all in one place by the &#x201C;Gang of Four&#x201D; (&#x201C;GoF&#x201D;), Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in their seminal book, <a href="https://smile.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8/?ref=appcoda.com">&#x201C;Design Patterns: Elements of Reusable Object-Oriented Software.&#x201D;</a></p>]]></description><link>https://www.appcoda.com/design-pattern-creational/</link><guid isPermaLink="false">66612a0f166d3c03cf011473</guid><category><![CDATA[Swift]]></category><dc:creator><![CDATA[Andrew Jaffee]]></dc:creator><pubDate>Tue, 24 Jul 2018 17:56:44 GMT</pubDate><media:content url="https://www.appcoda.com/content/images/wordpress/2018/07/fabian-grohs-550489-unsplash.jpg" medium="image"/><content:encoded><![CDATA[
<!--kg-card-begin: html-->
<img src="https://www.appcoda.com/content/images/wordpress/2018/07/fabian-grohs-550489-unsplash.jpg" alt="Design Patterns in Swift #1: Factory Method and Singleton"><p>There are 23 classic software development design patterns probably first identified,  collected, and explained all in one place by the &#x201C;Gang of Four&#x201D; (&#x201C;GoF&#x201D;), Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in their seminal book, <a href="https://smile.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8/?ref=appcoda.com">&#x201C;Design Patterns: Elements of Reusable Object-Oriented Software.&#x201D;</a> This tutorial focuses on two of those patterns in terms of what the GoF calls the &#x201C;creational&#x201D; category: <em>factory method</em> and <em>singleton</em>.</p>
<p>Software development is an endeavor into modeling real world scenarios in the hopes of creating tools to enhance the human experience in such scenarios. Tools for managing finances, e.g., banking apps and shopping aids like Amazon or eBay&#x2019;s iOS apps, definitely make life much simpler than it was for consumers just ten years ago. Think of how far we&#x2019;ve come. While software apps have generally gotten more powerful and simpler to use for consumers, development of said apps has gotten <a href="http://iosbrain.com/blog/2018/04/29/controlling-chaos-why-you-should-care-about-adding-error-checking-to-your-ios-apps/?ref=appcoda.com#chaos">much more complex</a> for developers.</p>
<p>So developers have created an arsenal of best practices to manage complexity, like <a href="http://iosbrain.com/blog/2017/02/26/intro-to-object-oriented-principles-in-swift-3-via-a-message-box-class-hierarchy/?ref=appcoda.com">object-oriented programming</a>, <a href="https://www.appcoda.com/pop-vs-oop/">protocol-oriented programming</a>, <a href="http://iosbrain.com/blog/2018/03/28/protocol-oriented-programming-in-swift-is-it-better-than-object-oriented-programming/?ref=appcoda.com#value_semantics">value semantics</a>, <a href="http://iosbrain.com/blog/2018/03/28/protocol-oriented-programming-in-swift-is-it-better-than-object-oriented-programming/?ref=appcoda.com#local_reasoning">local reasoning</a>, breaking large pieces of code into smaller ones with well-defined interfaces (like <a href="http://iosbrain.com/blog/2017/01/28/swift-extensions-managing-complexity-improving-readability-extensibility-protocols-delegates-uicollectionview/?ref=appcoda.com">with Swift extensions</a>), <a href="http://iosbrain.com/blog/2018/01/27/writing-expressive-meaningful-and-readable-code-in-swift-4/?ref=appcoda.com">syntactic sugar</a>, to name some of the most popular. One of the most important best practices that I didn&#x2019;t mention, but that merits much attention, is the use of design patterns.</p>
<h2>Design Patterns</h2>
<p>Design patterns are an extremely important tool with which developers can manage complexity. It&#x2019;s best to conceptualize them as generally templated techniques, each tailored to solving a corresponding, recurring, and readily identifiable problem. Look at them as a list of best practices you would use for coding scenarios that you see over and over again, like how to create objects from a related family of objects without having to understand all the gory implementation details of that family. The whole point of design patterns is that they apply to commonly occurring scenarios. They&#x2019;re reusable because they&#x2019;re generalized. A specific example should help.</p>
<p>Design patterns are not specific to some use case like iterating over a Swift array of 11 integers (<code>Int</code>). For example, the GoF defined the <em>Iterator</em> pattern to provide a common interface for traversing through all items in some collection without knowing the intricacies (i.e., type) of the collection. A design pattern is not programming language code. It is a set of guidelines or rule of thumb for solving a common software scenario.</p>
<p>Remember that I discussed the <a href="https://www.appcoda.com/mvvm-vs-mvc/">&#x201C;Model-View-ViewModel&#x201D; or &#x201C;MVVM&#x201D;</a> design pattern here on AppCoda &#x2014; and of course the very well-known <a href="https://www.appcoda.com/mvvm-vs-mvc/">&#x201C;Model-View-Controller&#x201D; or &#x201C;MVC&#x201D;</a> design pattern, long favored by Apple and many iOS developers.</p>
<p>These two patterns are generally applied to <em>entire applications</em>. MVVM and MVC are <em>architectural</em> design patterns and are meant to separate the user interface (UI) from the app&#x2019;s data and from code for presentation logic, and to separate the app&#x2019;s data from core data processing and/or business logic. The GoF design patterns are more specific in nature, meant to solve more specific problems <em>inside</em> an application&#x2019;s code base. You may use three or seven or even twelve GoF design patterns in one app. Remember my <em>Iterator</em> example. Delegation is <a href="https://www.appcoda.com/swift-delegate/">another great example</a> of a design pattern, though not specifically on the GoF&#x2019;s list of 23.</p>
<p>While the GoF book has taken on biblical connotations for many developers, it is not without its detractors. We&#x2019;ll talk about that in the conclusion to this article.</p>
<h3>Design pattern categories</h3>
<p>The GoF organized their 23 design patterns into 3 categories, &#x201C;creational,&#x201D; &#x201C;structural,&#x201D; and &#x201C;behavioral.&#x201D; This tutorial discusses two patterns in the <em>creational</em> category. This  pattern&#x2019;s purpose is to make the creation of (often complex) objects straightforward (easy), understandable, and maintainable for developers, hiding details like instantiation and class implementation.</p>
<p><a href="http://iosbrain.com/blog/2017/02/26/intro-to-object-oriented-principles-in-swift-3-via-a-message-box-class-hierarchy/?ref=appcoda.com#advantages">Hiding complexity (encapsulation)</a> is one the highest goals of smart developers. For example, object-oriented (OOP) classes can provide very complex, sophisticated, and powerful functionality without requiring the developer to know anything about the internal workings of those classes. In the creational pattern, a developer may not even have to know about a class&#x2019;s key properties and methods, but if necessary, she/he can take a peek at the interface &#x2014; protocol in Swift &#x2014; to the class(es) of interest and just plug and play. You&#x2019;ll see what I mean in our first example of a &#x201C;factory method&#x201D; design pattern.</p>
<h2>The factory method design pattern</h2>
<p>If you&#x2019;ve delved into the GoF design patterns and/or spent a lot of time in the world of OOP, you&#x2019;ve probably at least heard of the &#x201C;abstract factory,&#x201D; &#x201C;factory,&#x201D; or &#x201C;factory method&#x201D; pattern. While we could quibble over &#x201C;exact&#x201D; nomenclature, the example I&#x2019;m going to show you here most closely fits the &#x201C;factory method&#x201D; pattern.</p>
<p>In this paradigm, you can create very useful objects <em>without</em> directly calling class constructors and <em>without</em> knowing anything about the class(es) or class hierarchy that your factory method is instantiating. You get a lot of bang for cheap. You get functionality and UI (if applicable) with a minimal amount of code. So my factory method example project, available on <a href="https://github.com/appcoda/FactoryMethodInSwift?ref=appcoda.com">GitHub</a>, showcases how objects from a nontrivial class hierarchy can be used easily by, say, a team&#x2019;s UI developer:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/07/Factory_Method.gif" alt="Design Patterns in Swift #1: Factory Method and Singleton" width="392" height="712" class="aligncenter size-full wp-image-13767"></p>
<p>Most successful apps have a consistent look &#x2014; a theme &#x2014; that is pleasing and becomes associated with the app and/or app developer. We&#x2019;ll assume that all shapes used in our hypothetical app will be the same color and same size so as to stay in tune with the app&#x2019;s theme &#x2014; it&#x2019;s <em>branding</em>. These shapes could be useful through an app as custom buttons, or maybe just part of background imagery during the onboarding process.</p>
<p>Let&#x2019;s assume that the design team has agreed that my app theming code has been selected to be used as app background imagery. We&#x2019;ll go through my code, starting with the protocol, class hierarchy, and factory methods that our hypothetical UI developer shouldn&#x2019;t have to worry about.</p>
<p>See file <code>ShapeFactory.swift</code>. Here&#x2019;s a protocol for drawing shapes inside preexisting view controllers. Since it could be used for a variety of purposes, it&#x2019;s access level is public:</p>
<pre class="swift">
// these values have been pre-selected by
// the graphics and design teams
let defaultHeight = 200
let defaultColor = UIColor.blue

protocol HelperViewFactoryProtocol {
    
    func configure()
    func position()
    func display()
    var height: Int { get }
    var view: UIView { get }
    var parentView: UIView { get }
    
}
</pre>
<p>Remember that the <code>UIView</code> class has a rectangular <a href="https://developer.apple.com/documentation/uikit/uiview/1622621-frame?ref=appcoda.com"><code>frame</code></a> by default, so it was simplest for me to make <code>Square</code> my base shape class:</p>
<pre class="swift">
fileprivate class Square: HelperViewFactoryProtocol {
    
    let height: Int
    let parentView: UIView
    var view: UIView
    
    init(height: Int = defaultHeight, parentView: UIView) {
        
        self.height = height
        self.parentView = parentView
        view = UIView()
        
    }
    
    func configure() {
        
        let frame = CGRect(x: 0, y: 0, width: height, height: height)
        view.frame = frame
        view.backgroundColor = defaultColor
        
    }
    
    func position() {
        
        view.center = parentView.center
        
    }

    func display() {
        
        configure()
        position()
        parentView.addSubview(view)
        
    }
    
} // end class Square
</pre>
<p>Notice that I&#x2019;m taking advantage of OOP to reuse my code and thus make my shape hierarchy simple and maintainable. Classes <code>Circle</code> and <code>Rectangle</code> are just specializations of <code>Square</code> (and remember how easy it is to draw a circle by starting with a perfect square):</p>
<pre class="swift">
fileprivate class Circle : Square {
    
    override func configure() {
        
        super.configure()
        
        view.layer.cornerRadius = view.frame.width / 2
        view.layer.masksToBounds = true
        
    }
    
} // end class Circle

fileprivate class Rectangle : Square {
    
    override func configure() {
        
        let frame = CGRect(x: 0, y: 0, width: height + height/2, height: height)
        view.frame = frame
        view.backgroundColor = UIColor.blue
        
    }
    
} // end class Rectangle
</pre>
<p>I&#x2019;ve used <code>fileprivate</code> to emphasize one of the purposes behind the factory method pattern: <em>hiding complexity</em>. You should also see how the shape class hierarchy could be easily modified or extended without changing the factory methods below. Here&#x2019;s the code for the factory methods that makes object creation so abstract and simple:</p>
<pre class="swift">
enum Shapes {
    
    case square
    case circle
    case rectangle
    
}

class ShapeFactory {
    
    let parentView: UIView
    
    init(parentView: UIView) {
        
        self.parentView = parentView
        
    }
    
    func create(as shape: Shapes) -&gt; HelperViewFactoryProtocol {
        
        switch shape {
            
        case .square:
            
            let square = Square(parentView: parentView)
            return square
            
        case .circle:
            
            let circle = Circle(parentView: parentView)
            return circle
            
        case .rectangle:
            
            let rectangle = Rectangle(parentView: parentView)
            return rectangle
            
        }
        
    } // end func display
    
} // end class ShapeFactory

// Public factory method to display shapes.
func createShape(_ shape: Shapes, on view: UIView) {
    
    let shapeFactory = ShapeFactory(parentView: view)
    shapeFactory.create(as: shape).display()
    
}

// Alternative public factory method to display shapes.
// Technically, the factory method should return one of
// a number of related classes.
func getShape(_ shape: Shapes, on view: UIView) -&gt; HelperViewFactoryProtocol {
    
    let shapeFactory = ShapeFactory(parentView: view)
    return shapeFactory.create(as: shape)
    
}
</pre>
<p>Notice that I&#x2019;ve developed a class factory and two factory methods to give you some food for thought. Technically, a factory method should return one of a number of related classes, all with common base class and/or a common protocol. Since the purpose here was to draw a shape in a view, I personally prefer the <code>createShape(_:view:)</code> method. Sometimes it&#x2019;s a good idea to provide alternatives &#x2014; or just to experiment and explore new possibilities.</p>
<p>Finally, I show the use of two factory methods to draw shapes. The UI developer doesn&#x2019;t have to know anything about how the shape classes are encoded. He/she especially doesn&#x2019;t have to worry about how shape classes are initialized. The code in file <code>ViewController.swift</code> is easily readable:</p>
<pre class="swift">
import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func drawCircle(_ sender: Any) {
        
        // just draw the shape
        createShape(.circle, on: view)
        
    }
    
    @IBAction func drawSquare(_ sender: Any) {

        // just draw the shape
        createShape(.square, on: view)
        
    }
    
    @IBAction func drawRectangle(_ sender: Any) {

        // actually get an object from the factory
        // and use it to draw the shape
        let rectangle = getShape(.rectangle, on: view)
        rectangle.display()
        
    }
    
} // end class ViewController
</pre>
<h2>The singleton design pattern</h2>
<p>Most iOS developers are familiar with the singleton pattern. Think of the <code>UNUserNotificationCenter.current()</code>, <code>UIApplication.shared</code>, or <code>FileManager.default</code> singletons that you <em>have</em> to use if you want to send notifications, or open a URL in Safari, or manipulate iOS files, respectively. Singletons can be good for protecting shared resources, providing access to some system which contains one and only one instance of an object, supporting one object which performs some type of app-wide coordination, and, as we&#x2019;ll see here, can be good for providing a value-added wrapper of a built-in iOS singleton.</p>
<p>To act as a singleton, we make sure that a class:</p>
<ul>
<li>declares and initializes a <em>static</em> and constant property <em>of itself</em>, and calls that property <code>shared</code> to convey the fact that an instance of the class is a singleton (public by default);<p></p>
</li>
<li>declares a <em>private</em> property of some resource we want to control/protect but also share via <code>shared</code>; and,<p></p>
</li>
<li>
<p>declares a <em>private</em> initializer so that only our singleton class can initialize itself, and inside this <code>init</code>, we initialize the resource we want to control but also share.</p>
</li>
</ul>
<p>By making the class&#x2019;s initializer <code>private</code> and defining the <code>shared</code> static constant, we&#x2019;ve ensured that there can only be one instance of the class, the class can only initialize itself once, and the class&#x2019;s <code>shared</code> instance is accessible throughout our app code. We&#x2019;ve created a&#x2026; <em>singleton</em>!</p>
<p>My singleton example project, available on <a href="https://github.com/appcoda/SingletonInSwift?ref=appcoda.com">GitHub</a>, showcases how a development team can store user preferences safely, consistently, and with very few errors. Here&#x2019;s my sample app remembering whether the user prefers to see their password as unencrypted plain text or as masked, which is not the greatest idea in retrospect, but I needed an example to show you that my code works. This code is <em>solely</em> for educational purposes. I advise you <strong>never</strong> to leave a password exposed. Here&#x2019;s how the user can set her/his password preference &#x2014; and that preference is saved in <code>UserDefaults</code>:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/07/Show_Pwd.gif" alt="Design Patterns in Swift #1: Factory Method and Singleton" width="392" height="274" class="aligncenter size-full wp-image-13769"></p>
<p>When the user closes and eventually comes back to the app, note that her/his password preference is remembered:</p>
<p><img loading="lazy" decoding="async" src="https://www.appcoda.com/content/images/wordpress/2018/07/Remember_Pwd_Setting.gif" alt="Design Patterns in Swift #1: Factory Method and Singleton" width="392" height="274" class="aligncenter size-full wp-image-13768"></p>
<p>Let me show you an excerpt of the code in file <code>PreferencesSingleton.swift</code>, with inline commentary, and you&#x2019;ll see exactly what I mean:</p>
<pre class="swift">
class UserPreferences {

    // Create a static, constant instance of
    // the enclosing class (itself) and initialize.
    static let shared = UserPreferences()
    
    // This is the private, shared resource we&apos;re protecting.
    private let userPreferences: UserDefaults
    
    // A private initializer can only be called by
    // this class itself.
    private init() {
        
        // Get the iOS shared singleton. We&apos;re
        // wrapping it here.
        userPreferences = UserDefaults.standard
        
    }

} // end class UserPreferences
</pre>
<p>There&#x2019;s no need to worry about impact on, say, app startup as initializers of static properties and global variables are run lazily, as I understand Swift.</p>
<p>You may ask, &#x201C;Why has he created a singleton wrapper of another singleton, <code>UserDefaults</code>?&#x201D; First, my main purpose herein was to show you a best practice for creating and using a singleton in Swift, and user preferences is the type of resource that should have a single point of entry. So <code>UserDefaults</code> served a very obvious didactic example. But secondly, think about how many times you&#x2019;ve seen <code>UserDefaults</code> used (abused) almost flippantly through an app&#x2019;s code base.</p>
<p>I&#x2019;ve seen apps where <code>UserDefaults</code> (or <code>NSUserDefaults</code> in the &#x201C;old&#x201D; days) were spread all over project code without any rhyme or reason. Every single reference to a key in user preferences was spelling out by hand. I just found a bug in my own code where I had misspelled the word &#x201C;switch&#x201D; as &#x201C;swithc,&#x201D; and because I had copied and pasted, I had ended up with quite a few instances of &#x201C;swithc&#x201D; before I caught the problem. What if other team member(s) on that app started or continued to used &#x201C;switch&#x201D; as a key in saving the corresponding value? The app could&#x2019;ve ended up with two or more states being preserved for what should&#x2019;ve been one state. <code>UserDefaults</code> uses strings as the keys to the values we wish to maintain as part of app state, which is fine because it&#x2019;s best to describe something &#x2014; values &#x2014; with meaningful, easily identified, and easily remembered words. But strings are not without risk.</p>
<p>Many of you have probably read about what has become known as &#x201C;stringly-typed&#x201D; code, as in my discussion about &#x201C;swithc&#x201D; vs. &#x201C;switch.&#x201D; While strings are very descriptive &#x2014; a good thing &#x2014; the use of raw strings as unique identifiers all over a code base is likely to lead to subtle yet eventually catastrophic errors because of misspellings. The Swift compiler doesn&#x2019;t prevent us from making stringly-typed mistakes.</p>
<p>The solution to stringly-typed errors is making use of string constants in the form of the Swift <code>enum</code>. Not only can we standardize our use of strings, but we can organize them by breaking them into categories. Again, see <code>PreferencesSingleton.swift</code>:</p>
<pre class="swift">
...
class UserPreferences {
    
    enum Preferences {
        
        enum UserCredentials: String {
            case passwordVisibile
            case password
            case username
        }
        
        enum AppState: String {
            case appFirstRun
            case dateLastRun
            case currentVersion
        }

    } // end enum Preferences
...
</pre>
<p>I&#x2019;m starting to wander from the definition of the singleton design pattern, but I do want to briefly show you and explain why I myself use a singleton wrapper for <code>UserDefaults</code> in most of my production apps. There are many value-added features that can make a <code>UserDefaults</code> singleton wrapper very convenient and enhance the reliability of code. Providing error checking when getting and setting preferences immediately comes to mind. Another feature I like to add is providing convenience methods for commonly used user preferences, like for how to handle passwords. You&#x2019;ll see below as you read my code. Here&#x2019;s everything in my <code>PreferencesSingleton.swift</code> file:</p>
<pre class="swift">
import Foundation

class UserPreferences {
    
    enum Preferences {
        
        enum UserCredentials: String {
            case passwordVisibile
            case password
            case username
        }
        
        enum AppState: String {
            case appFirstRun
            case dateLastRun
            case currentVersion
        }

    } // end enum Preferences
    
    // Create a static, constant instance of
    // the enclosing class (itself) and initialize.
    static let shared = UserPreferences()
    
    // This is the private, shared resource we&apos;re protecting.
    private let userPreferences: UserDefaults
    
    // A private initializer can only be called by
    // this class itself.
    private init() {
        
        // Get the iOS shared singleton. We&apos;re
        // wrapping it here.
        userPreferences = UserDefaults.standard

    }
    
    func setBooleanForKey(_ boolean:Bool, key:String) {
        
        if key != &quot;&quot; {
            userPreferences.set(boolean, forKey: key)
        }
        
    }
    
    func getBooleanForKey(_ key:String) -&gt; Bool {
        
        if let isBooleanValue = userPreferences.value(forKey: key) as! Bool? {
            print(&quot;Key \(key) is \(isBooleanValue)&quot;)
            return true
        }
        else {
            print(&quot;Key \(key) is false&quot;)
            return false
        }
        
    }
    
    func isPasswordVisible() -&gt; Bool {
        
        let isVisible = userPreferences.bool(forKey: Preferences.UserCredentials.passwordVisibile.rawValue)
        
        if isVisible {
            return true
        }
        else {
            return false
        }
        
    }

    func setPasswordVisibity(_ visible: Bool) {
        
        userPreferences.set(visible, forKey: Preferences.UserCredentials.passwordVisibile.rawValue)
        
    }

} // end class UserPreferences
</pre>
<p>If you look at my <code>ViewController.swift</code> file, you&#x2019;ll see how easy it is to access and make use of a well-constructed singleton:</p>
<pre class="swift">
import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var passwordTextField: UITextField!
    @IBOutlet weak var passwordVisibleSwitch: UISwitch!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        if UserPreferences.shared.isPasswordVisible() {
            passwordVisibleSwitch.isOn = true
            passwordTextField.isSecureTextEntry = false
        }
        else {
            passwordVisibleSwitch.isOn = false
            passwordTextField.isSecureTextEntry = true
        }
        
    } // end func viewDidLoad

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    @IBAction func passwordVisibleSwitched(_ sender: Any) {
        
        let pwdSwitch:UISwitch = sender as! UISwitch
        
        if pwdSwitch.isOn {
            passwordTextField.isSecureTextEntry = false
            UserPreferences.shared.setPasswordVisibity(true)
        }
        else {
            passwordTextField.isSecureTextEntry = true
            UserPreferences.shared.setPasswordVisibity(false)
        }
        
    } // end func passwordVisibleSwitched
    
} // end class ViewController
</pre>
<h2>Conclusion</h2>
<p>Some critics have claimed that use of design patterns is proof of deficiencies in programming languages and that seeing recurring patterns in code is a bad thing. I disagree. Expecting a language to have a feature for <em>everything</em> is silly and would most likely lead to enormous languages like C++ into becoming even larger and more complex and thus harder to learn, use, and maintain. Recognizing and solving recurring problems is a positive human trait worthy of positive reinforcement. Design patterns are successful examples of learning from history, something humankind has failed to do too many times. Coming up with abstract and standardized solutions to common problems makes those solutions portable and more likely to be distributed.</p>
<p>A combination of a compact language like Swift and an arsenal of best practices, like design patterns, is an ideal and happy medium. Consistent code is generally readable and maintainable code. Remember too that design patterns are ever-evolving as millions of developers are constantly discussing and sharing ideas. By virtue of being linked together over the World Wide Web, this developer discussion has lead to constantly self-regulating collective intelligence.</p>

<!--kg-card-end: html-->
]]></content:encoded></item></channel></rss>