<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Software Development on Andrew Bancroft</title>
    <link>https://www.andrewcbancroft.com/categories/software-development/</link>
    <description>Recent content about iOS development with Swift in Software Development  from Andrew Bancroft.</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 19 Jan 2015 18:40:12 +0000</lastBuildDate>
    
        <atom:link href="https://www.andrewcbancroft.com/categories/software-development/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Fix MAMP, MySQL Workbench “Failed to Connect to MySQL”</title>
      <link>https://www.andrewcbancroft.com/2015/01/19/fix-mamp-mysql-workbench-failed-connect-mysql/</link>
      <pubDate>Mon, 19 Jan 2015 18:40:12 +0000</pubDate>
      
      <guid>https://www.andrewcbancroft.com/2015/01/19/fix-mamp-mysql-workbench-failed-connect-mysql/</guid>
      <description>&lt;p&gt;Installing &lt;a href=&#34;http://www.mamp.info/&#34;&gt;MAMP&lt;/a&gt; was easy. I did, however, spend at least 45 minutes trying to get MySQL Workbench to connect to my local MySQL database server. The solution was simple, but getting there led me around the Internet and back with little help. Hopefully this signpost will help others having connection issues with MySQL Workbench to MAMP MySQL servers as well.&lt;/p&gt;
&lt;p&gt;Once MAMP is installed and the MySQL server has started, you&amp;rsquo;ll be taken to a start screen that looks something like this:&lt;br&gt;
&lt;a href=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/MAMP_StartScreen.png&#34;&gt;&lt;img src=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/MAMP_StartScreen.png&#34; alt=&#34;MAMP Start Screen Port Number&#34; width=&#34;601&#34; height=&#34;411&#34; class=&#34;alignnone size-full wp-image-11187&#34; srcset=&#34;https://www.andrewcbancroft.com/wp-content/uploads/2015/01/MAMP_StartScreen.png 601w, https://www.andrewcbancroft.com/wp-content/uploads/2015/01/MAMP_StartScreen-300x205.png 300w&#34; sizes=&#34;(max-width: 601px) 100vw, 601px&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The information presented there is misleading.&lt;/strong&gt; The start page instructs you to use port 3306. So I did:&lt;br&gt;
&lt;a href=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/SettingsBasedOnStartScreen.png&#34;&gt;&lt;img src=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/SettingsBasedOnStartScreen.png&#34; alt=&#34;Settings based on MAMP Start Screen&#34; width=&#34;897&#34; height=&#34;515&#34; class=&#34;alignnone size-full wp-image-11185&#34; srcset=&#34;https://www.andrewcbancroft.com/wp-content/uploads/2015/01/SettingsBasedOnStartScreen.png 897w, https://www.andrewcbancroft.com/wp-content/uploads/2015/01/SettingsBasedOnStartScreen-300x172.png 300w&#34; sizes=&#34;(max-width: 897px) 100vw, 897px&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When testing the connection, however, I got the dreaded &amp;ldquo;Failed to Connect to MySQL at localhost”:&lt;br&gt;
&lt;a href=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/ErrorOnTestConnection.png&#34;&gt;&lt;img src=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/ErrorOnTestConnection.png&#34; alt=&#34;Error on Test Connection&#34; width=&#34;412&#34; height=&#34;146&#34; class=&#34;alignnone size-full wp-image-11184&#34; srcset=&#34;https://www.andrewcbancroft.com/wp-content/uploads/2015/01/ErrorOnTestConnection.png 412w, https://www.andrewcbancroft.com/wp-content/uploads/2015/01/ErrorOnTestConnection-300x106.png 300w&#34; sizes=&#34;(max-width: 412px) 100vw, 412px&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It turns out that MAMP has a preferences panel wherein you can configure the ports for your Apache and MySQL servers. And of course, MySQL was &lt;em&gt;not&lt;/em&gt; set to use port 3306, as the start page led me to believe. Rather, it was set to use port 8889:&lt;br&gt;
&lt;a href=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/MAMP_Preferences_Port.png&#34;&gt;&lt;img src=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/MAMP_Preferences_Port.png&#34; alt=&#34;MAMP Preferences Port Number&#34; width=&#34;529&#34; height=&#34;400&#34; class=&#34;alignnone size-full wp-image-11186&#34; srcset=&#34;https://www.andrewcbancroft.com/wp-content/uploads/2015/01/MAMP_Preferences_Port.png 529w, https://www.andrewcbancroft.com/wp-content/uploads/2015/01/MAMP_Preferences_Port-300x227.png 300w&#34; sizes=&#34;(max-width: 529px) 100vw, 529px&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adjusting the settings to use the port listed in the MAMP preferences pane led to a successful connection!&lt;br&gt;
&lt;a href=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/SettingsBasedOnMAMPPreferences1.png&#34;&gt;&lt;img src=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/SettingsBasedOnMAMPPreferences1.png&#34; alt=&#34;Settings based on MAMP Preferences&#34; width=&#34;897&#34; height=&#34;515&#34; class=&#34;alignnone size-full wp-image-11198&#34; srcset=&#34;https://www.andrewcbancroft.com/wp-content/uploads/2015/01/SettingsBasedOnMAMPPreferences1.png 897w, https://www.andrewcbancroft.com/wp-content/uploads/2015/01/SettingsBasedOnMAMPPreferences1-300x172.png 300w&#34; sizes=&#34;(max-width: 897px) 100vw, 897px&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Good to go!&lt;br&gt;
&lt;a href=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/GoodToGo.png&#34;&gt;&lt;img src=&#34;http://www.andrewcbancroft.com/wp-content/uploads/2015/01/GoodToGo.png&#34; alt=&#34;Good to go!&#34; width=&#34;414&#34; height=&#34;144&#34; class=&#34;alignnone size-full wp-image-11190&#34; srcset=&#34;https://www.andrewcbancroft.com/wp-content/uploads/2015/01/GoodToGo.png 414w, https://www.andrewcbancroft.com/wp-content/uploads/2015/01/GoodToGo-300x104.png 300w&#34; sizes=&#34;(max-width: 414px) 100vw, 414px&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Distinguishing Between Multiple UIActionSheets with Swift</title>
      <link>https://www.andrewcbancroft.com/2014/11/16/distinguishing-between-multiple-uiactionsheets-with-swift/</link>
      <pubDate>Mon, 17 Nov 2014 04:17:39 +0000</pubDate>
      
      <guid>https://www.andrewcbancroft.com/2014/11/16/distinguishing-between-multiple-uiactionsheets-with-swift/</guid>
      <description>&lt;p&gt;The challenge when dealing with the presentation and handling of more than one &lt;code&gt;UIActionSheet&lt;/code&gt; in a single View Controller is made clear by asking, &amp;ldquo;How am I going to tell which action sheet I&amp;rsquo;m dealing with so that I can handle the user&amp;rsquo;s choice appropriately?”&lt;/p&gt;
&lt;p&gt;Presumably, the user&amp;rsquo;s interaction with one of the action sheets will be different than the other(s), so you&amp;rsquo;ll need to think through how to distinguish between them, in order to respond to that interaction appropriately.&lt;/p&gt;
&lt;p&gt;I faced such a scenario in a recent project, and I thought I&amp;rsquo;d share my solution. Check out my &lt;a href=&#34;https://github.com/andrewcbancroft/DistinguishingActionSheetsExample&#34; title=&#34;GitHub Example&#34;&gt;GitHub example&lt;/a&gt; to dive in if you prefer learning by exploration!&lt;/p&gt;
&lt;h3 id=&#34;using-uiview-tags&#34;&gt;Using UIView Tags&lt;/h3&gt;
&lt;p&gt;Essentially, I chose to make use of the &lt;code&gt;tag&lt;/code&gt; property, which all UIView subclasses inherit. The &lt;a href=&#34;https://developer.apple.com/library/iOS//documentation/UIKit/Reference/UIView_Class/index.html#//apple_ref/occ/instp/UIView/tag&#34; title=&#34;UIView Class Reference - Tag Property&#34;&gt;UIView Class Reference documentation specifies&lt;/a&gt; that the &lt;code&gt;tag&lt;/code&gt; property can be used to identify the view at runtime:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can set the value of this tag and use that value to identify the view later.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s a quick example showing the setting of this property so that the action sheet can be differentiated when it comes time to handle the user&amp;rsquo;s choice:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;actionSheet1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UIActionSheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;actionSheet1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// set other properties, such as delegate, as well as buttons...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;actionSheet2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UIActionSheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;actionSheet2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// set other properties, such as delegate, as well as buttons...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;better-solution-in-swift&#34;&gt;Better Solution in Swift?&lt;/h3&gt;
&lt;p&gt;Simple enough, right? Here&amp;rsquo;s my only problem with the above implementation if I&amp;rsquo;m using Swift: We have language features available to us that allow us to avoid setting the tag property to the integer value in-line like I did in this code snippet.&lt;/p&gt;
&lt;p&gt;Here, instead of assigning in-line, I&amp;rsquo;m going to refactor and employ a Swift enumeration to help &lt;em&gt;name&lt;/em&gt; the tag. Underneath, there will still be integers involved, but my goal in using an enumeration is two-fold:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Identify the action sheet in code with a name. This should help my code be more coherent and readable.&lt;/li&gt;
&lt;li&gt;Encapsulate a single source of truth for the tag values and avoid &amp;ldquo;magic integers” in my code. While the integers assigned to the tags can be arbitrary, if they ever &lt;em&gt;do&lt;/em&gt; need to be changed, I change the enumeration, rather than changing each place where the tag is set or checked to perform branching logic.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The arguments are fundamentally the same as those I made when I &lt;a href=&#34;http://www.andrewcbancroft.com/2014/09/02/replace-magic-strings-with-enumerations-in-swift/&#34; title=&#34;Replace Magic Strings with Enumerations in Swift&#34;&gt;wrote about replacing magic strings in Swift&lt;/a&gt; and implement precisely the same strategy.&lt;/p&gt;
&lt;h3 id=&#34;refactored-example&#34;&gt;Refactored Example&lt;/h3&gt;
&lt;p&gt;The refactored version of the code snippet previously presented could look like this, then:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;enum&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ActionSheetTag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;// Integer values will be implicitly supplied; you could optionally set your own values&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ActionSheet1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ActionSheet2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;actionSheet1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UIActionSheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;actionSheet1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ActionSheetTag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ActionSheet1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;toRaw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// set other properties, such as delegate, as well as buttons...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;actionSheet2&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UIActionSheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;actionSheet2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ActionSheetTag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ActionSheet2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;toRaw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// set other properties, such as delegate, as well as buttons...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s worth noting that rather than using an enumeration, I could have chosen to define a couple of constants at a scope visible to both my setting of the tag, and the conditional logic I&amp;rsquo;d use in my UIActionSheetDelegate callback. The end goal and result would be the same: Clarity, achieved by assigning &lt;em&gt;names&lt;/em&gt; to the tags, and the avoidance of &amp;ldquo;magic integers” appearing in my code.&lt;/p&gt;
&lt;h3 id=&#34;wrapping-up--uiactionsheetdelegate-implementation&#34;&gt;Wrapping Up – UIActionSheetDelegate Implementation&lt;/h3&gt;
&lt;p&gt;To see how to perform the conditional logic needed in the UIActionSheetDelegate callback method, take a look at this final code snippet:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;actionSheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;actionSheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UIActionSheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clickedButtonAtIndex&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;buttonIndex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ActionSheetTag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fromRaw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;actionSheet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ActionSheet1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;handleActionSheet1Interaction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Function definition omitted for brevity, but ideally you&amp;#39;d implement a function to do something in response to the user&amp;#39;s interaction with ActionSheet 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ActionSheet2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;handleActionSheet2Interaction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// // Function definition omitted for brevity, but ideally you&amp;#39;d implement a function to do something in response to the user&amp;#39;s interaction with ActionSheet 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;bp&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Unknown action sheet.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve done it before, but by using Swift enumerations again in a new context, I was able to provide better clarity to the intention of my code when I had multiple UIActionSheet instances that I needed to handle in a single view controller. In addition to this clarity, I also encapsulated a single source of truth for identifying my UIActionSheet instances, rather than placing &amp;ldquo;magic integers” throughout my code. Have a look at (and play with) &lt;a href=&#34;https://github.com/andrewcbancroft/DistinguishingActionSheetsExample&#34; title=&#34;GitHub Example&#34;&gt;the example I&amp;rsquo;ve put up on GitHub&lt;/a&gt; for further study and improvement!&lt;/p&gt;
&lt;div class=&#34;related-posts&#34;&gt;
  You might also enjoy&lt;/p&gt; 
  &lt;ul&gt;
    &lt;li&gt;
      &lt;a href=&#34;http://www.andrewcbancroft.com/2014/09/02/replace-magic-strings-with-enumerations-in-swift/&#34; title=&#34;Replace Magic Strings with Enumerations in Swift&#34;&gt;Replace Magic Strings with Enumerations in Swift&lt;/a&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;a href=&#34;http://www.andrewcbancroft.com/2014/10/01/swift-alternative-to-objective-c-macros/&#34; title=&#34;Swift Alternative to Objective-C Macros&#34;&gt;Swift Alternative to Objective-C Macros&lt;/a&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;
</description>
    </item>
    
  </channel>
</rss>