<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Use Your Loaf]]></title>
  <link href="http://useyourloaf.com/blog/atom.xml" rel="self"/>
  <link href="http://useyourloaf.com/"/>
  <updated>2012-05-26T17:09:00+01:00</updated>
  <id>http://useyourloaf.com/</id>
  <author>
    <name><![CDATA[Keith Harrison]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Making Some Changes]]></title>
    
      <category term="blog"/>
    
    <link href="http://useyourloaf.com/blog/2012/05/25/making-some-changes.html"/>
    <updated>2012-05-25T16:22:00+01:00</updated>
    <id>http://useyourloaf.com/blog/2012/05/25/making-some-changes</id>
    <content type="html"><![CDATA[<p>If you are reading this post then it means some changes to this blog that I have been working on this week have gone live. If you subscribe to the RSS feed this probably also means that you have just seen the last ten posts show up again in your RSS reader. My apologies for that but I hope the end result is worth the temporary disturbance.</p>

<h3>Ancient History</h3>

<p>For more than two years this blog has been hosted on <a href="http://squarespace.com">SquareSpace.com</a> and for the most part I have been very happy with the service. If you are looking for a quick, easy and relatively cheap way to get a blog up and running it is an option well worth considering.</p>

<p>However I think it is time to make some changes to get the site closer to the way I want it. What follows is a brief description of what I have been up to this week.</p>

<h3>Static Blog using Octopress</h3>

<p>This is a very simple blog with very simple requirements so I have for a while been wanting to move to a static blog engine rather than a complex content management system such as SquareSpace or WordPress. With a static blog all of the content can be checked into a version control repository of my choosing allowing me complete freedom on how and where I host the site.</p>

<p>There are many static blog engines to choose from but I chose to use <a href="http://octopress.org">Octopress</a> a framework developed by <a href="http://brandonmathis.com/">Brandon Mathis</a> for <a href="http://github.com/mojombo/jekyll">Jekyll</a>. It already has plugins for everything that I could possibly want, works well in both desktop and mobile browsers and I figured that if it is good enough for <a href="http://mattgemmell.com/2011/09/12/blogging-with-octopress/">Matt Gemmell</a> it is surely good enough for me.</p>

<p>I will spare you the details of the migration as it mostly involved cleaning up the html export of my SquareSpace blog. The biggest pain was in fixing the URL&#8217;s of some posts and converting everything back to markdown format. I also had to convert the comments to the Wordpress XML comment format so that I could import them to Disqus. If you are really interested I posted the ruby script I used to convert both the posts and the comments in this <a href="https://gist.github.com/2783345">Gist</a>.</p>

<h3>Disqus Comments</h3>

<p>Early on I had a lot of problems with comment spam on squarespace but the comment moderation seems to have improved a lot lately. The iOS App also makes it easy to manage comments even though it seems to crash way too frequently. However with the move to a static blog I needed to reconsider what to do about comments.</p>

<p>It seems a lot of sites are now just disabling comments on the grounds that they are a pain to manage and often do not add any value. I really appreciate the feedback and suggestions I get in the comments on this site so I have decided to move them to <a href="http://disqus.com">Disqus</a>.</p>

<p>You do not currently need to have a Disqus account to leave a comment but I may change that setting in the future if Spam becomes a problem. You do need to specify an email address when posting but it is never displayed. Also note that to access the comment thread from the blog home page you need to first click on the individual blog post.</p>

<h3>Linode</h3>

<p>The final change this week has been to move the blog to a <a href="http://www.linode.com/?r=b33a255648781feb4512e8cb377d00d2081b7d5a">Linode (referral link)</a> hosted VPS and set up the web server. A static blog has no need for a backend database and does not need PHP, ruby, perl or any other means to generate dynamic content. As a result I opted for the smallest VPS node that Linode offers at a price that is comparable to what I was paying for the Squarespace site.</p>

<h3>Summary</h3>

<p>It is early days to say how well the migration has gone but so far I think it is a big improvement over the previous site. For me the extra administration involved in managing the whole site is a price worth paying but I guess you do need to be comfortable with some basic sys admin to make it work. So far I am pretty happy with the results. As always feedback and suggestions are welcome.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Detecting VoiceOver Status Changes]]></title>
    
      <category term="accessibility"/>
    
    <link href="http://useyourloaf.com/blog/2012/05/14/detecting-voiceover-status-changes.html"/>
    <updated>2012-05-14T20:26:00+01:00</updated>
    <id>http://useyourloaf.com/blog/2012/05/14/detecting-voiceover-status-changes</id>
    <content type="html"><![CDATA[<p><em>This is a follow up to my recent post about adding <a href="http://useyourloaf.com/blog/2012/04/23/voiceover-accessibility.html">VoiceOver Accessibility</a> support to an iOS app to cover situations where you need to adjust the user interface when VoiceOver is active.</em></p>

<h3>Gestures and Accessibility</h3>

<p>I generally dislike Apps that rely exclusively on gestures such as touches, swipes or shaking the device to perform an operation. The gestures may well have been obvious to the developer but as a user I often struggle to discover what I am supposed to do. This leads to a situation where you end up randomly touching, pinching and swiping the screen to discover &#8220;hidden&#8221; features. This not only leads to a poor user experience but also presents real challenges to accessibility as the gestures are generally not available when VoiceOver is active.</p>

<p>I like to think of gestures as being the equivalent of a keyboard shortcut for a desktop application. The keyboard shortcut allows power users to perform an operation more efficiently but a toolbar icon or menu option allows a normal user to discover and perform the same operation. Likewise if an app makes use of a gesture it should generally have some visible on-screen control that can be used to perform the same operation. A good example is the common iOS gesture of swiping to delete a row in a table. If you are not aware of the gesture you can still use the edit button in the toolbar and then use the on-screen controls to delete rows. This also removes any issues with VoiceOver as long as you set the accessibility attributes for the on-screen controls.</p>

<p>Relying on a gesture as the only way to access a feature not only makes your app difficult to use with VoiceOver it also makes your app difficult to use for all users. Having said that if you have a situation where you really do not want to have an on-screen control you should at least consider modifying the user interface of the app when VoiceOver is active.</p>

<p>Another example that can cause accessibility issues can occur when you are displaying some information for a limited period of time. For example you might keep some details about a download on-screen for a few seconds after it completes. Using VoiceOver those few seconds might not be enough time for the user to navigate to, select and have VoiceOver read the label. In both cases we need to be able to detect VoiceOver status and change the behaviour and maybe even the user interface when it is active.</p>

<h3>Revisiting the Task Timer</h3>

<p>I previously created a simple task management app to show the basic techniques involved in adding VoiceOver support. The full details are contained in this <a href="http://useyourloaf.com/blog/2012/04/23/voiceover-accessibility.html">previous post</a> but the basic idea was to allow the user to create tasks and then time how long they took to complete. I am going to add a new feature to the app which will allow us to reset the duration of a task by shaking the device. This is just the sort of bad user interface design that I was referring to earlier but one which I hope will illustrate the idea.</p>

<p>Before we take a look at detecting whether VoiceOver is active we need to go on a small diversion to implement the shake to reset feature. Luckily this turns out to be trivial. When a user shakes a device the accelerometer generates motion events. The motion events can be received by any subclass of UIResponder but we need to make sure that our view controller can become the first responder:</p>

<pre><code>- (BOOL)canBecomeFirstResponder
{
  return YES;
}
</code></pre>

<p>We do not care in which direction the device is shaken so to detect the shake we implement motionEnded:withEvent: in the task view controller:</p>

<pre><code>- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
  [self taskResetAction];
}
</code></pre>

<p>I will not bother showing the details of the taskResetAction here as it is not relevant to this discussion. You can check the code if you are interested. Note that there is no way to test device shaking in the simulator so you will need to deploy to an actual device if you want to verify that the shake event actually works. The shake action will still work even if VoiceOver is activated but to improve the accessibility of the app we will look at how we can provide an alternative user interface when we detect VoiceOver is in use.</p>

<h3>Checking the Status of VoiceOver</h3>

<p>There are two ways to determine or be informed of the status of VoiceOver. The first way is to call the UIKit function UIAccessibilityIsVoiceOverRunning(). This returns a BOOL indicating if VoiceOver is active. The second way is to register for the UIAccessibilityVoiceOverStatusChanged notification. We will use both of these techniques to show a reset button in our detailed task view whenever VoiceOver is active:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-14-001.png" alt="" /></p>

<p>The first thing we will do is add the reset button to both the iPhone and iPad Nib files for the task view controller and connect its outlet and action. The reset button is just a UIButton with a custom image inserted into the task view as shown below:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-14-002.png" alt="" /></p>

<p>We can set the accessibility label for the button directly in Interface Builder:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-14-021.png" alt="" /></p>

<p>To ensure that the button is not normally visible we also set the hidden property in Interface Builder:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-14-003.png" alt="" /></p>

<p>Our view controller implements an IBOutlet property that is wired up to the button.</p>

<pre><code>@property (weak, nonatomic) IBOutlet UIButton *taskResetButton;
</code></pre>

<p>The button action is connected to the same taskResetAction we used previously to respond to the shaking motion event:</p>

<pre><code>- (IBAction)taskResetAction;
</code></pre>

<p>Now when our view first loads the viewDidLoad method in the view controller is used to configure the view. So we can use a call to UIAccessibilityIsVoiceOverRunning() to see if VoiceOver is already active and if so ensure our reset button is visible:</p>

<pre><code>self.taskResetButton.hidden = ! UIAccessibilityIsVoiceOverRunning();
</code></pre>

<p>That takes care of situations where VoiceOver is in use when our view loads but not if it is activated or disabled when our view is already onscreen. For that we need to register an observer for the notification in the viewDidLoad method:</p>

<pre><code>- (void)viewDidLoad
{
  ...
  ...

  [[NSNotificationCenter defaultCenter] addObserver:self 
                         selector:@selector(voiceOverStatusChanged)
                         name:UIAccessibilityVoiceOverStatusChanged
                         object:nil];
}
</code></pre>

<p>To be sure we clean up when our view controller goes away we should of course unregister the observer in viewDidUnload and dealloc. Since we are using ARC we have not so far implemented dealloc so we need to add it now just to remove the observer:</p>

<pre><code>- (void)dealloc
{
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}
</code></pre>

<p>The notification does not actually provide a parameter indicating the VoiceOver status but that is not an issue as we can simply call UIAccessibilityIsVoiceOverRunning again to get the current status. Depending on the status we can show or hide the reset button:</p>

<pre><code>- (void)voiceOverStatusChanged
{
  self.taskResetButton.hidden = ! UIAccessibilityIsVoiceOverRunning();
}
</code></pre>

<p>Now as we enable or disable VoiceOver with the task view visible the reset button is dynamically shown or hidden in response.</p>

<h3>Summary</h3>

<p>As I discussed at the start of this post if you find yourself needing to modify your app behaviour for VoiceOver it may actually be a warning of a more fundamental problem in your interface design. For those situations where you really do need to do something different I hope this post proves to be useful. You can find the modified Xcode project used in this post in my GitHub <a href="https://github.com/kharrison/CodeExamples/tree/master/TaskTimer">CodeExamples</a> repository.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Programming iOS 5 by Matt Neuburg]]></title>
    
      <category term="reviews"/>
    
    <link href="http://useyourloaf.com/blog/2012/05/10/programming-ios-5-by-matt-neuburg.html"/>
    <updated>2012-05-10T22:14:00+01:00</updated>
    <id>http://useyourloaf.com/blog/2012/05/10/programming-ios-5-by-matt-neuburg</id>
    <content type="html"><![CDATA[<p><em><a href="http://shop.oreilly.com/product/0636920023562.do"><img src="http://akamaicovers.oreilly.com/images/0636920023562/cat.gif" align="right"></a>My list of book <a href="http://useyourloaf.com/links/">resources</a> has lacked a strong recommendation for iOS for some time. There are a lot of good introduction to iOS programming books available but I struggle to recommend just one as the definitive guide. <a href="http://shop.oreilly.com/product/0636920023562.do">Programming iOS 5</a>, 2nd Edition by Matt Neuburg (O&#8217; Reilly Media, March 2012) is a major update to the author&#8217;s earlier Programming iOS 4 book which may just fill the gap.</em></p>

<h3>First Impressions</h3>

<p>The first thing I have to say is that this is a massive book with the dead-tree version weighing in at 1016 pages. Luckily I read the ePub version using iBooks which I prefer for technical books. You are going to want to annotate, highlight and bookmark for future reference with this book. You can read it from cover-to-cover but it will also serve you well as a reference book when you need to review topics. Note though that if you are looking for a tutorial or cookbook style approach this is probably not the book for you. I guess Matt may have received some criticism for the iOS 4 version of the book as he makes the purpose of this edition very clear up front:</p>

<blockquote><p>The purpose of this book is to proceed by focusing on the underlying knowledge needed for an actual understanding of iOS programming. That is precisely the opposite of a cookbook. This book has no simple recipes ready for you to drop into your own code and come up with an app. I don&#8217;t give you some fish; I teach you what a fish is and what you need to know to obtain one.</p></blockquote>

<p>Even though it is not a cookbook all of the code examples are available on <a href="https://github.com/mattneub/Programming-iOS-Book-Examples">GitHub</a> which is an approach I wish all authors would adopt. It makes it so much easier to browse code and also ensures that any minor typos get fixed quickly. Emphasis is given to features new to iOS 5 such as ARC and storyboarding which helps if you are transitioning from iOS 4 but no prior iOS knowledge is assumed.</p>

<h3>In Depth</h3>

<p>The book is divided into seven major sections as follows:</p>

<ul>
<li>Section I. Language</li>
<li>Section II. IDE</li>
<li>Section III. Cocoa</li>
<li>Section IV. Views</li>
<li>Section V. Interface</li>
<li>Section VI. Some Frameworks</li>
<li>Section VII. Final Topics</li>
</ul>


<p>The first five sections represent maybe two thirds of the book and step by step provide a thorough coverage of the fundamentals of iOS 5 development. A lot of iOS programming books either assume prior knowledge of C or include a quick summary in an Appendix. This books kicks off with coverage of both the C and Objective-C languages and then introduces Xcode and Nibs.</p>

<p>With the basics out of the way Cocoa is introduced by way of the foundation framework, categories and protocols, notifications, the delegation pattern, actions and the responder chain. It is also at this point that the detailed discussion of memory management is introduced which is a mandatory and key topic for any Cocoa book. The book is written with the assumption that you will be using ARC but also stresses that you still need to understand the Cocoa memory management model behind ARC.</p>

<p>The Views section provides good explanations on the view hierarchy, frames and coordinate systems, drawing, layers, animation, handling touches and gestures. The Interface section completes the fundamentals with coverage of view controllers, table views, popovers and split views and an exhaustive look at the numerous other views and controls.</p>

<p>The last two sections of the book tie up some loose ends with coverage of additional frameworks and topics that don&#8217;t fit elsewhere. This includes coverage of many of the more common frameworks including audio, video, music library, photo library, address book, calendar, mail, maps and sensors (e.g. location and acceleration). The final section finishes up with some quick coverage of file management, networking and threads (including both NSOperation and Grand Central Dispatch). The use of iCloud is also covered briefly in the discussion on the UIDocument model.</p>

<h3>Likes and Dislikes</h3>

<p>What I like about this book are the numerous hints, tips and opinions from Matt as he covers each topic. I don&#8217;t want to see a reproduction of reference material that I can just as easily get from Apple. What I want is insight into what an experienced developer thinks about the topic at hand. For example, there is a very good explanation of storyboards but what I found interesting about that section was Matt&#8217;s strong opinion on storyboards and why you might not want to use them. The explanation on popovers gets a similar treatment and in both cases I have to agree with the conclusions that Matt reaches.</p>

<p>There were so many new features introduced with iOS 5 that I think even somebody with iOS 4 experience will find this book useful. Changes from iOS 4 are highlighted throughout the book which should help when making the transition.</p>

<p>Even though this is a huge book there are still some topics that are not covered. It is easy to forget how big the iOS SDK has become so I think it is fine to skip topics like Game Kit, iAD integration, Printing, In App Purchase and the long list of other iOS Frameworks and topics. If you have a good understanding of the basics you should have no problem figuring out the less common frameworks on your own.</p>

<p>Personally I would have liked to see Core Data and maybe also Accessibility covered. I consider Core Data to be a fundamental Cocoa technology and as I <a href="http://useyourloaf.com/blog/2012/04/23/voiceover-accessibility.html">posted recently</a> I would like to see Accessibility get some more attention in general from developers and book authors. Section VI of the book covers a number of interesting but not vital frameworks such as accessing the music and photo libraries, the address book and calendar which I would exchange for some coverage of Core Data. That is a very minor criticism though for what is otherwise a comprehensive coverage of the iOS universe.</p>

<h3>Final Comments</h3>

<p>There is a lot to recommend about this book and I don&#8217;t just mean because of the size. The primary purpose of the book is to provide you with a deep understanding of the language and iOS frameworks and I think it succeeds in that task. Of course that takes some effort on the part of the reader and I can imagine that this book will not suit everybody. Clearly if you are looking for quick high level survey of iOS 5 with some sample code to get you started this is not the book for you. On the other hand if you are prepared to invest the time I would be surprised if even experienced iOS developers can read this book without learning something.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Static Table Views with Storyboards]]></title>
    
      <category term="storyboard"/>
    
    <link href="http://useyourloaf.com/blog/2012/05/07/static-table-views-with-storyboards.html"/>
    <updated>2012-05-07T14:14:00+01:00</updated>
    <id>http://useyourloaf.com/blog/2012/05/07/static-table-views-with-storyboards</id>
    <content type="html"><![CDATA[<p>When I first heard that iOS 5 had introduced the concept of a static table view that could be designed in Interface Builder I was disappointed to see that it was actually tied into storyboards. I have nothing against storyboards, they are an interesting innovation that can (potentially) save a lot of code. However if you are not yet ready to fully adopt storyboards for your user interface design you may be discouraged from exploring the new features they bring. What I want to examine in this post is how you can use a minimal implementation of storyboards to quickly create a static table view without having to completely rewrite an existing App.</p>

<h3>Designing A Settings Table</h3>

<p>Implementing a Settings table is an obvious use for static table views within an App. To illustrate how easy this is I am going to start from the Xcode template for a tabbed application. Note that I did not select the option to use storyboards so that the main interface is still created using the traditional Nib approach. (I am however using ARC so pay attention if you are cut and pasting code into an App not using ARC). The template gives us a tab bar controller containing two view controllers both loaded from individual Nib files. The second view controller is what we will replace with a storyboard to implement our application settings views.</p>

<p>To get started I am going to create a storyboard and layout a number of table views. To keep this post short I am going to limit this to an iPhone layout but the principle applies equally for an iPad or Universal App. To add a storyboard create a new file and select the storyboard from the User Interface templates, ensure the device family is set to iPhone and name the file <code>Settings</code>:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-03-001.png" alt="" /></p>

<p>The first table view controller that I am going to add to the storyboard is going to represent a top level settings menu allowing me to group simple and advanced settings which I will access on separate views. When I have finished the table view should look like this:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-03-002.png" alt="" /></p>

<p>By default when you drag a table view controller into a storyboard you get a dynamic table view. You can change this by selecting <code>Static Cells</code> in the Attributes Inspector:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-03-003.png" alt="" /></p>

<p>What we now have is a table view containing three empty cells that we can use to design our top level settings menu:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-03-004.png" alt="" /></p>

<p>To get to our desired layout the main steps are as follows:</p>

<ul>
<li>change the table view style from <code>Plain</code> to <code>Grouped</code> and delete two of the rows to leave a single row (you can change the number of rows using the Inspector but to delete a row it is quicker to just click on the rows in the table and hit the delete key)</li>
<li>drag a label object into the table view cell, adjust the formatting as you see fit and set the text label to <code>General</code></li>
<li>with the Table View Section selected in either the document navigator or in the jump bar use the Attributes Inspector to set the section header and footer (this is also where you would adjust the number of rows in the section):</li>
</ul>


<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-03-005.png" alt="" /></p>

<p>To add the second section ensure the Table View is selected in the document navigator and then change the number of sections in the Attributes Inspector. When the new section is added it is copied from the first section which is a nice time saver. To complete the layout we just need to modify the header, footer and label text.</p>

<p>Now we have our initial settings table view we can repeat the exercise to add our detailed settings tables but before we do that we need to embed our table view controller in a navigation controller to handle moving between the various tables. That is an easy step using the Embed In > Navigation Controller option from the Xcode Editor menu. Once the Navigation Controller has been added we can also set the title in the Navigation Bar for our Settings table view controller. At this point the Storyboard should look as follows:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-03-006.png" alt="" /></p>

<p>Now we can repeat the exercise for two additional table view controllers which will provide static table views for our simple and advanced settings. I will not go through this step by step but at the end of the process the Storyboard will look something like this:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-06-001.png" alt="" /></p>

<p>At this point we need to add the transitions from the Settings table view controller to each of the detailed settings view controllers. The Storyboard editor refers to each of the views as scenes and transitions between scenes as segues. We need two segues in this case, the first from the General table view cell to take us to the General Settings table view and the second from the Extra Settings table view cell to the Advanced Settings table view. To create the segues you need to control click on the source table view cell and then drag across to the destination table view. When you release the mouse button you are presented with a popover menu allowing you to select the Storyboard segue style. Since we are using a navigation controller we will use the push segue.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-06-002.png" alt="" /></p>

<p>With our new view controllers now included in the navigation hierarchy we can set the title for each view by typing directly in the navigation bar of each view so that our Storyboard now looks as follows (Interface Builder will infer when it needs to add the navigation and tab bars to views):</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-06-003.png" alt="" /></p>

<h3>Loading the storyboard</h3>

<p>If we were using a storyboard for the main user interface we could specify the filename in the UIMainStoryboardFile key in the application Info.plist file and it would be loaded automatically. Since in this example we want to make a more limited use of storyboards we need to manually load and launch our storyboard file. We can do that by modifying our Application Delegate to use the storyboard when loading the view controller for the second tab bar item. The relevant code in the application:didFinishLaunchingWithOptions method is as follows:</p>

<pre><code>UYLFirstViewController *firstViewController = [[UYLFirstViewController alloc]
                        initWithNibName:@"UYLFirstViewController"
                        bundle:nil];
UIStoryboard *settingsStoryboard = [UIStoryboard 
                                    storyboardWithName:@"Settings"
                                    bundle:nil];
UIViewController *settingsViewConroller = [settingsStoryboard
                                        instantiateInitialViewController];

settingsViewConroller.title = NSLocalizedString(@"Settings", @"Settings");
settingsViewConroller.tabBarItem.image = [UIImage imageNamed:@"second"];

self.tabBarController = [[UITabBarControlleralloc] init];
self.tabBarController.viewControllers = [NSArray
                      arrayWithObjects:firstViewController,
                      settingsViewConroller, nil];
self.window.rootViewController = self.tabBarController;
</code></pre>

<p>Lines 2 and 3 are the important ones, the UIStoryboard class method storyBoardWithName:bundle: is used to load the Storyboard file. There is no need to specify the bundle when the storyboard is contained in the main application bundle. The instantiateInitialViewController method then allocates and initialises our root navigation view controller which we can then add to the tab bar view controller along with the first view controller which was created from its Nib file.</p>

<p>Now if we run the App in the Simulator a lot the Settings table view is already working including pushing and popping the detailed view controllers on and off the navigation controller stack. So far this looks like a real win for storyboards in that we have a lot of functionality designed in Interface Builder without having to write any boilerplate view controller code. Since our initial settings table view controller only acts as a top level menu it appears that we do not even need to implement a custom subclass for it (I say &#8220;appears&#8221; as we will see shortly that there is one issue we need to deal with that causes us to create a generic table view subclass).</p>

<h3>Implementing Row Selection</h3>

<p>To actually make our settings screens useful we need to implement the view controllers so that we can interact with the user interface and read and write the settings. The general settings screen (shown below) is the easiest so we will start by adding a subclass of UITableViewController named UYLGeneralSettingsTableViewController.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-06-004.png" alt="" /></p>

<p>The public interface for this class is empty:</p>

<pre><code>@interface UYLGeneralSettingsTableViewController : UITableViewController
@end
</code></pre>

<p>We will add two properties to the private class extension to represent to two settings (speed and volume) that this view manipulates:</p>

<pre><code>@interface UYLGeneralSettingsTableViewController ()

@property (nonatomic) NSUInteger speed;
@property (nonatomic) NSUInteger volume;

@end
</code></pre>

<p>Now we need to implement just enough of a table view controller to allow us to setup the view state when it first loads and to allow us to change the selected row in each of the two sections. Before I show the code that I added it is important to note the code that I do NOT need to implement:</p>

<ul>
<li>the UITableViewDataSource protocol has two required methods and a number of optional methods that are now largely redundant. Of the two normally required methods I will in this case implement tableView:cellForRowAtIndexPath: (to set the checkmark of the selected row) but it may not always be required.</li>
<li>There is no need to implement the other required method tableView:numberOfRowsInSection: or numberOfSectionsInTableView: as the table dimensions of the static table were set in InterfaceBuilder.</li>
<li>We do not need to implement tableView:titleForHeaderInSection: or tableView:titleForFooterInSection: as we directly set the header and footer in the Storyboard.</li>
</ul>


<p>To initialise the view we will implement the viewDidLoad method to read our user defaults from file.</p>

<pre><code>- (void)viewDidLoad
{
    [superviewDidLoad];

    NSUserDefaults *defaults = [NSUserDefaultsstandardUserDefaults];
    self.speed = [defaults integerForKey:kUYLSettingsSpeedKey];
    self.volume = [defaults integerForKey:kUYLSettingsVolumeKey];
}
</code></pre>

<p>Now to actually set the checkmark on the currently selected row we will implement the UITableViewDataSource protocol method tableView:cellForRowAtIndexPath:</p>

<pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [super tableView:tableView
                             cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryNone;

    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];

    switch (section)
    {
        case SECTION_SPEED:
            if (row == self.speed)
            {
                cell.accessoryType = UITableViewCellAccessoryCheckmark;
            }
            break;

        case SECTION_VOLUME:
            if (row == self.volume)
            {
                cell.accessoryType = UITableViewCellAccessoryCheckmark;
            }
            break;
    }
    return cell;
}
</code></pre>

<p>Usually the first thing you do in tableView:cellForRowAtIndexPath is attempt to dequeue a cell for reuse of if not available allocate and initialise a new UITableViewCell. However that does not apply in this case as this is a static table view. All of the table view cells that we need were created in Interface Builder and are instantiated when the storyboard loads the view controller. By the way this is worth considering if you are attempting to use static table views to create a huge table view. Having to allocate all of the static table view cells when the view is first loaded may be both slow and cause you memory issues. If you find yourself creating a static table view with more than one or two screens of information you probably want to go back to using a dynamic table view.</p>

<p>Even though we do not need to allocate the table view cells for a static table view we can still get a reference to each cell to allow us to customise the cell. There are several ways to do this including declaring an outlet for each table view cell in Interface Builder which we will see in the advanced settings view controller. In this case though we simply need to set the cell accessory type so we can call tableView:cellForRowAtIndexPath on the super class to return us the current cell. Once we have the current cell we can set or clear the accessoryType based on the current value of the speed or volume properties.</p>

<p>We also need to implement the UITableViewDelegate method to handle row selection (see below). There is nothing remarkable about this method so I will not go into too much details. The method basically just updates the user defaults based on which row is selected and then requests the table view is reloaded to cause the checkmarks to be set.</p>

<pre><code>- (void)tableView:(UITableView *)tableView
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];

    switch (section)
    {
        case SECTION_SPEED:
            self.speed = row;
            [defaults setInteger:row forKey:kUYLSettingsSpeedKey];
            break;
        case SECTION_VOLUME:
            self.volume = row;
            [defaults setInteger:row forKey:kUYLSettingsVolumeKey];
            break;
    }
    [self.tableView reloadData];
}
</code></pre>

<p>Finally we need to go back to Interface Builder and with the Identity inspector change the class of the generic UITableViewController to our custom subclass UYLGeneralSettingsTableViewController:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-06-005.png" alt="" /></p>

<p>If you rerun the App in the Simulator the general settings screen should now be fully functional.</p>

<h3>Connecting to Static Table View Cells</h3>

<p>The advanced settings screen at first looks a little more complicated as we have a number of switches and stepper controls that we need to interact with. In fact whilst it takes a little bit of effort in Interface Builder wiring everything up it actually requires even less code. As before we will start by adding a subclass of UITableViewController to the project and name it UYLAdvancedSettingsViewController:</p>

<pre><code>@interface UYLAdvancedSettingsViewController : UITableViewController
@end
</code></pre>

<p>To be able to interact with the contents of the static table view cells we need to define some outlets to allow us to set the various elements and action methods for the switch and stepper controls. A good place to do that is in a private class extension of our custom subclass:</p>

<pre><code>@interface UYLAdvancedSettingsViewController ()

- (IBAction)switchToggled:(UISwitch *)sender;
- (IBAction)stepperChanged:(UIStepper *)sender;

@property (nonatomic, weak) IBOutlet UISwitch *warpSwitch;
@property (nonatomic, weak) IBOutlet UISwitch *shieldsSwitch;
@property (nonatomic, weak) IBOutlet UILabel *creditsLabel;
@property (nonatomic, weak) IBOutlet UILabel *retriesLabel;
@property (nonatomic, weak) IBOutlet UIStepper *creditsStepper;
@property (nonatomic, weak) IBOutlet UIStepper *retriesStepper;

@end
</code></pre>

<p>This project is compiled using ARC so we follow Apple recommendations and make all of our IBOutlet properties weak references. Now we use Interface Builder to connect the outlets to the corresponding label or control in the static table view. To do that we first need to use the Identity inspector to change the class of the view from the generic UITableViewController to our custom UYLAdvancedSettingsViewController. I will not walk you through wiring up every user interface element as it is standard Interface Builder stuff but just for reference the view hierarchy and connections are reproduced below:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-06-006.png" alt="" /></p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-06-007.png" alt="" /></p>

<p>In order to determine which switch or stepper is triggering the action each one is uniquely tagged within Interface builder.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-06-008.png" alt="" /></p>

<p>Now we have our outlets wired up it is trivial in viewDidLoad to set the initial state of the switches, steppers and labels:</p>

<pre><code>- (void)viewDidLoad
{
  [superviewDidLoad];

  NSUserDefaults *defaults = [NSUserDefaultsstandardUserDefaults];

  self.warpSwitch.on = [defaults boolForKey:kUYLSettingsWarpDriveKey];
  self.shieldsSwitch.on = [defaults boolForKey:kUYLSettingsShieldsKey];

  self.creditsStepper.value = [defaults doubleForKey:kUYLSettingsCreditsKey];
  self.creditsLabel.text = [NSStringstringWithFormat:@"%1.0f",
                            self.creditsStepper.value];

  self.retriesStepper.value = [defaults doubleForKey:kUYLSettingsRetriesKey];
  self.retriesLabel.text = [NSStringstringWithFormat:@"%1.0f",
                            self.retriesStepper.value];
}
</code></pre>

<p>Note that we do not need to implement tableView:cellForRowAtIndexPath: to get a cell reference as we have direct access to each cell via the outlets. In fact we do not need to implement any UITableViewDataSource or UITableViewDelegate method. The two action methods to handle the switch and stepper actions are fairly similar so I will just show the method for the switch here:</p>

<pre><code>- (IBAction)switchToggled:(UISwitch *)sender
{
    NSUserDefaults *defaults = [NSUserDefaultsstandardUserDefaults];

    switch (sender.tag)
    {
        case TAG_WARPSWITCH:
            [defaults setBool:sender.on forKey:kUYLSettingsWarpDriveKey];
            break;

        case TAG_SHIELDSSWITCH:
            [defaults setBool:sender.on forKey:kUYLSettingsShieldsKey];
            break;
    }
}
</code></pre>

<h3>Handling Orientation Changes</h3>

<p>There is one small issue I need to take care of before finishing. As currently implemented there is a problem with the way that we respond to device rotation. In fact if you build and run the App you will see that it does not respond to device orientation changes. The general rule for a tab bar controller is that all of the view controllers in each tab need to allow rotation or nothing rotates. I have not shown it but each of the view controllers we have implemented, including the view controller used for the first tab bar item, implements shouldAutorotateToInterfaceOrientation: to return YES for all orientations:</p>

<pre><code>- (BOOL)shouldAutorotateToInterfaceOrientation:
        (UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}
</code></pre>

<p>Unfortunately there is one view controller, the top level settings table view controller which messes things up for us. Since we did not need to interact with the table we never actually implemented our own custom subclass for this table view controller. That means we cannot override the orientation method so we get the default behaviour:</p>

<blockquote><p>By default, this method returns YES for the UIInterfaceOrientationPortrait orientation only. If your view controller supports additional orientations, override this method and return YES for all orientations it supports.</p></blockquote>

<p>To resolve this issue I have added a new UITableViewController subclass named UYLRotatingTableViewController that does nothing else but implement the shouldAutorotateToInterfaceOrientation method. Using the Identity inspector to change the class of the settings table view controller to this new subclass fixes the problem. The final storyboard is as follows:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-05-07-001.png" alt="" /></p>

<h3>Wrapping Up</h3>

<p>One of the criticisms I have heard about storyboards is that unless your App is very simple they do not save you very much code. This is because you still need to handle the flow of data between view controllers. Typically this involves implementing prepareForSeque:Sender: to pass data into a new view controller and implementing a delegate protocol to pass data back to a parent or presenting view controller.</p>

<p>In this example we are making a very limited use of storyboards and there is no real data flow between the different static table view controllers. This means there is no need to implement prepareForSegue:sender: or to create view controller delegates so there is a considerable reduction in the amount of code required. You can make your own mind up on the value of storyboards and when they might be appropriate. Personally I like the ability to add them selectively to an App for specific parts of the interface and static table views are definitely one area where I will use them.</p>

<p>As always you can download the example Xcode project that accompanies this post <a href="http://useyourloaf.com/assets/code/StaticTable.zip">here</a> or in my Github <a href="https://github.com/kharrison/CodeExamples/tree/master/StaticTable">CodeExamples</a> repository.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Xcode Balancing Brackets For Method Calls]]></title>
    
      <category term="Xcode"/>
    
    <link href="http://useyourloaf.com/blog/2012/04/27/xcode-balancing-brackets-for-method-calls.html"/>
    <updated>2012-04-27T20:18:00+01:00</updated>
    <id>http://useyourloaf.com/blog/2012/04/27/xcode-balancing-brackets-for-method-calls</id>
    <content type="html"><![CDATA[<p><em>This may well be my favourite and perhaps also the simplest Xcode completion trick I have come across. I may be the last person to discover it but just in case there is somebody else who is yet to find it&#8230;</em></p>

<p>I always find it a pain to think about how many opening brackets (&#8220;[&#8220;) I need when starting to write Objective-C statements where you have several nested method calls. This means I often get to the end of the statement and find I have an extra opening bracket somewhere. Luckily Xcode will allow you to forget about the opening brackets and just type the closing brackets. The corresponding opening bracket is inserted for you by Xcode automatically. So for example assume I start typing the following sequence:</p>

<pre><code>NSNumber *number10 = NSNumber alloc
</code></pre>

<p>At this point (with the cursor at the end of the line) typing a single closing bracket &#8220;]&#8221; causes Xcode to insert the corresponding opening bracket so you end up with this:</p>

<pre><code>NSNumber *number10 = [NSNumber alloc]
</code></pre>

<p>If I then continue to type the rest of the statement I can repeat the same trick at this point:</p>

<pre><code>NSNumber *number10 = [NSNumber alloc] initWithInteger:10 
</code></pre>

<p>Typing the final closing &#8220;]&#8221; again causes Xcode to insert the corresponding initial &#8220;[&#8221; to give us the following:</p>

<pre><code>NSNumber *number10 = [[NSNumber alloc] initWithInteger:10]
</code></pre>

<p>Adding the final semicolon completes the statement:</p>

<pre><code>NSNumber *number10 = [[NSNumber alloc] initWithInteger:10];
</code></pre>

<p>If for some strange reason you do not like this code completion you can disable it in Xcode preferences (look under Code completion in the Text Editing preferences pane).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[VoiceOver Accessibility]]></title>
    
      <category term="accessibility"/>
    
    <link href="http://useyourloaf.com/blog/2012/04/23/voiceover-accessibility.html"/>
    <updated>2012-04-23T19:47:00+01:00</updated>
    <id>http://useyourloaf.com/blog/2012/04/23/voiceover-accessibility</id>
    <content type="html"><![CDATA[<p>Apple has made it really easy to add VoiceOver support to iOS Apps. In many cases setting the accessibility label for each interface element in Interface Builder gets 90% of the job done. What I want to cover in this post is the remaining 10% that will ensure an App interacts well with VoiceOver. If you have never considered making your App accessible you should read this great post by Matt Gemmell on <a href="http://mattgemmell.com/2010/12/19/accessibility-for-iphone-and-ipad-apps/">Accessibility for iPhone and iPad apps</a>.</p>

<h3>What is VoiceOver?</h3>

<p>VoiceOver is a technology built into all iOS (and Mac) devices that provides audible aids to the user when navigating and interacting with an App. The UIAccessibility API was introduced with version 3.0 of the SDK to allow the app to provide additional information to VoiceOver. This includes such things as setting the label and optionally a hint that is read by VoiceOver when an element in the user interface is selected. In addition you set accessibility traits for each UI element indicating for example that it acts like a button or whether or not it has been selected.</p>

<p>The easiest way to understand VoiceOver is to try it on some existing apps and get a feel for how it works. Before diving into an example app I will quickly review how to access VoiceOver and some other tools that you will want to use when testing your App.</p>

<h3>Toggling VoiceOver Support on a Device</h3>

<p>You can turn VoiceOver support on for a device from the Settings application (Settings > General > Accessibility > VoiceOver). However for testing purposes I find it more convenient to be able to quickly switch VoiceOver on and off from within the App. To do that I set the Triple-click Home button option to Toggle VoiceOver (from the Settings > General > Accessibility screen):</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-03-27-voiceover.png" alt="" /></p>

<p>With this option enabled you can easily turn VoiceOver on and off at any point by triple-clicking the Home button on the device. This makes it easy to examine specific situations in your App with and without VoiceOver activated. It can also be an education to enable VoiceOver on other Apps to see how well or badly other developers are handling accessibility.</p>

<h3>Accessibility Inspector in the iOS Simulator.</h3>

<p>The iOS Simulator does not directly support VoiceOver so you will always need to test on a device to see how well your App performs. However the iOS Simulator does have an extremely useful tool for debugging UIAccessibility issues. It is called the Accessibility Inspector and it can be activated on the Simulator from Settings > General > Accessibility. Once enabled you should see the inspector window displayed:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-03-27-inspector.png" alt="" /></p>

<p>The Accessibility Inspector does not speak to you but it does provide you with information about the currently selected accessible element. The Inspector can be temporarily disabled/enabled by clicking the close control in the upper left corner of the Inspector. This can be useful when you need to navigate around the app as you can selectively enable the inspector to examine each element in your user interface.</p>

<h3>TaskTimer - An Example in Adding Accessibility</h3>

<p>The rest of this post is going to be a case study in adding VoiceOver support to an example App called TaskTimer. The app is based on the Xcode Master Detail template and is a variation on a task list manager - the variation being that you can time how long a particular task takes. This is a universal app so both iPhone and iPad User Interfaces are supported. The master view is a UITableView containing the list of tasks as shown in the iPhone screenshot below:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-07-001.png" alt="" /></p>

<p>The task list follows the usual conventions of a table view in that new tasks can be inserted using the &#8220;+&#8221; button in the navigation bar and deleted via the &#8220;Edit&#8221; button. The actual task data is stored in a core data model. A completed task is shown by the green tick and the actual duration (mm:ss) is shown under the task name in the table cell view. The App is somewhat limited in that it only handles task durations up to 59 minutes 59 seconds long but it is good enough for the purposes of this post. Selecting a row in the table shows the detail view for the selected task which allows the task name to be edited. In addition a custom view allows the task timer to be stopped and started via two buttons with the current task duration displayed in a central text label:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-07-002.png" alt="" /></p>

<p>As I mentioned this is a Universal app so just for completeness the iPad user interface is shown below in portrait orientation:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-07-003.png" alt="" /></p>

<h3>UITableView Accessibility</h3>

<p>If we use the Accessibility Inspector in the iOS Simulator we can see how well this App performs before we make any modifications. If we first take a look at the Task List table view we can find some UI elements that work fine and others that definitely need some work. The standard Navigation bar elements such as the Edit button, the title and the Add button all work fine without any effort on our part:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-09-001.png" alt="" /></p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-09-002.png" alt="" /></p>

<p>Note how the accessibility traits indicate that the first UI element is a button where as the second element is static text. Correctly setting the accessibility traits of an element is key to ensuring that VoiceOver interacts correctly with the App. Standard iOS UIKit elements such as the Navigation Bar are generally already properly configured. Simple UI elements can also be configured in Interface Builder when creating the interface.</p>

<p>Things are not so good if we look at one of the rows in the table for a completed task:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-09-003.png" alt="" /></p>

<p>By default the table view cell has combined the main text label and the detailed text label for the accessibility label. The two fields are separated by a comma which means VoiceOver will pause briefly when reading the label. This is fine but VoiceOver does not understand that 00:10 actually means 0 minutes, 10 seconds - it simply reads &#8220;zero - ten&#8221; which is not very informative. Note also that there is no mention of the status of the task. In this case the green tick indicates that the task has been completed but the VoiceOver interface is unable to present that piece of information to the user.</p>

<p>So to improve the accessibility of this view we should in the first instance address the following issues:</p>

<ul>
<li>Ensure that when VoiceOver reads the task details it correctly interprets the duration making it clear that it is a time.</li>
<li>We should also ensure that the task completion status is indicated for each row in the list</li>
</ul>


<p>One thing we could also do is add a hint to the table view cell indicating that selecting a row will take the user to the detail task view. In this case I consider that unnecessary as I think it is OK to assume that users understand the basic iOS user interface idioms.</p>

<p>To customise the response from VoiceOver for a UITableView cell we simply need to set the accessibilityLabel property when we configure the cell in the table view controller. In the situation where the task is not yet completed and so does not have a final duration we will stick with the default provided by the cell text label which is the name of the task (task.note). However when the task is complete (task.complete) we want to both indicate the completion status and read the duration in a human friendly way. The following code added to the configureCell:atIndexPath method in UYLTaskListViewController should do the job:</p>

<pre><code>cell.accessibilityLabel = task.note;

if ([task.complete boolValue])
{
  NSUInteger minutes = [task.duration integerValue] / 60;
  NSUInteger seconds = [task.duration integerValue] % 60;

  cell.detailTextLabel.text = [NSString stringWithFormat:@"%02u:%02u",
                               minutes, seconds];
  cell.imageView.image = [UIImage imageNamed:@"checked.png"];

  NSString *durationText = [NSString stringWithFormat:@"%@ %@",
                            task.note,
                            NSLocalizedString(@"completed in", nil)];
  durationText = [durationText stringByAppendingString:
                               [task.duration stringValueAsTime]];
  cell.accessibilityLabel = durationText;
}
</code></pre>

<p>To generate the text to represent the duration I have created a category (UYLTimeFormatter) on the NSNumber class to add the method stringValueAsTime since we will need it more than once. An example of the output using the Accessibility Inspector is shown below:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-11-001-1.png" alt="" /></p>

<h3>Custom View Accessibility</h3>

<p>So far adding VoiceOver support has been very easy since it has just involved setting the accessibilityLabel for certain key UI elements. However for the detailed task view things get slightly more complicated. A custom class UYLCounterView is used to implement the numeric counter and the two buttons used to start and stop the counter. By default the buttons will use either the title if set or the name of the UIImage file to provide an accessibility label.  In this case I am using images named start.png and stop.png which provides a reasonable default but note that these labels are of course not localised.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-18-001.png" alt="" /></p>

<p>A more serious problem though is that the value of the counter is not accessible at all. The problem is that the text is drawn in the view using a drawAtPoint method so there is no way to directly set an accessibilityLabel or other accessibility properties for the counter. The solution is to implement the <strong>UIAccessibilityContainer Protocol</strong> for the custom view. This allows us to define arbitrary rectangles in the view that represent the elements we want to make accessible. In this case the view contains three elements, the start button, the stop button and the counter that we want to make accessible.</p>

<p>The UIAccessibilityContainer protocol is an informal protocol so we do not need to declare anything in our UYLCounterView class indicating that we are adopting it. What we will need though is a mutable array to hold our accessible elements. The following property is added to the UYLCounterView interface definition:</p>

<pre><code>@property (nonatomic, strong) NSMutableArray *accessibleElements;
</code></pre>

<p>We need to create and configure a UIAccessibilityElement object for each of the three elements in our custom view and store them in this array. To avoid unnecessary effort when VoiceOver is not active we will lazily create them in the getter method in the UYLCounterView implementation. The first thing we do therefore in the getter is to check if we have already created the array and if not we allocate it:</p>

<pre><code>- (NSArray *)accessibleElements
{
  if (_accessibleElements != nil)
  {
      return_accessibleElements;
  }

  _accessibleElements = [[NSMutableArray alloc] init];
</code></pre>

<p>Now we need to create a UIAccessibilityElement and correctly set the accessibility properties for each view element. We need to add the elements to the accessibleElements array in the order they are presented to the user from top-left to bottom-right. So the first element we will create is for the start button:</p>

<pre><code>  UIAccessibilityElement *startElement = [[UIAccessibilityElement alloc]
                          initWithAccessibilityContainer:self];
  startElement.accessibilityFrame = [self convertRect:self.startButton.frame
                                     toView:nil];
  startElement.accessibilityLabel = NSLocalizedString(@"Start", nil);
  startElement.accessibilityTraits = UIAccessibilityTraitButton;
  if (self.startButton.enabled == NO)
    startElement.accessibilityTraits |= UIAccessibilityTraitNotEnabled;

  [_accessibleElements addObject:startElement];
</code></pre>

<p>Some notes about each of the above lines of code</p>

<ul>
<li><p>A UIAccessibilityElement is created using the initWithAccessibilityContainer instance method. This method takes a single parameter which is the containing view. In this case the UYLCounterView is the containing view so we can simply use self.</p></li>
<li><p>The accessibilityFrame property is where we specify the area of the view that we want to use for this accessibility element. For the start button this is just the frame of the UIButton but note that <strong>the accessibility frame must be specified in screen coordinates</strong>. This is an important point to understand, if you use the view coordinate system you will get unexpected results especially when the view rotates (more on handling view rotation later). The easiest way to convert the button frame to the screen coordinates is to use the UIView instance method convertRect:toView: specifying nil as the target view, this will give us a frame in the screen coordinate system.</p></li>
<li><p>Once we have an accessibility element allocated we can set the accessibilityLabel as with standard UIKit controls. We can, if required, also set an accessibilityHint but in this case we will just set the label to &#8220;Start&#8221;.</p></li>
<li><p>The accessibilityTraits property is this case indicates that this element behaves as a button</p></li>
<li><p>We need to provide VoiceOver with a indication when the button is enabled/disabled. Usually a UIButton will take care of this for us but since we are creating our own accessibility element to represent the button we need to add the UIAccessibilityTraitNotEnabled trait when the button is not enabled.</p></li>
<li><p>Finally we add the element to our array of accessibileElements.</p></li>
</ul>


<p>The next element represents the text drawn in the centre of the view for the timer counter. Calculating the frame for the text is complicated by the need to convert between the view and screen coordinate systems. The code to create the accessibilityElement for the counter is as follows:</p>

<pre><code>CGRect frame = [self convertRect:self.accessibilityFramefromView:nil];

UIAccessibilityElement *counterElement = [[UIAccessibilityElement alloc]
                        initWithAccessibilityContainer:self];
CGRect textFrame = CGRectInset(frame, UYLCOUNTERVIEW_MARGIN + 
                                      self.startButton.bounds.size.width +
                                      UYLCOUNTERVIEW_MARGIN,
                                      UYLCOUNTERVIEW_MARGIN);
counterElement.accessibilityFrame = [self convertRect:textFrame toView:nil];
counterElement.accessibilityLabel = NSLocalizedString(@"Duration", nil);
counterElement.accessibilityValue = [[NSNumber
                                      numberWithInteger:self.secondsCounter]
                                      stringValueAsTime];
counterElement.accessibilityTraits = UIAccessibilityTraitUpdatesFrequently;

[_accessibleElements addObject:counterElement];
</code></pre>

<p>Note that in this case we start by converting the accessibilityFrame of the view to our local view coordinate system from the screen coordinate system. We can then calculate the frame for the text using an inset for the margin and size of the buttons. Finally before setting the accessibilityFrame for the element we need to convert back again to screen coordinates.</p>

<p>As well as setting the accessibilityLabel for this element we also set an accessibilityValue string to represent the current value of the counter. We will see how this gets updated later but note that for elements that can have a value which changes (such as volume control) it is better to use the accessibilityLabel to describe the function of the control and accessibilityValue to represent the current value. In this case the label is set to &#8220;Duration&#8221; and the value will the actual value of the counter (for example &#8220;2 minutes 10 seconds&#8221;).</p>

<p>Since the value of the counter can update frequently (in this case once a second) we set the UIAccessibilityTraitUpdatesFrequently trait. We will discuss the impact of this attribute and some other options once we have seen the rest of the setup code.</p>

<p>Finally we add the element for the stop button and return the completed array. Since the stop button code is very similar to the code for the start button I will include the code without further comment:</p>

<pre><code>  UIAccessibilityElement *stopElement = [[UIAccessibilityElement alloc]
                                  initWithAccessibilityContainer:self];
  stopElement.accessibilityFrame = [self convertRect:self.stopButton.frame
                                    toView:nil];
  stopElement.accessibilityLabel = NSLocalizedString(@"Stop", nil);
  stopElement.accessibilityTraits = UIAccessibilityTraitButton;
  if (self.stopButton.enabled == NO)
     stopElement.accessibilityTraits |= UIAccessibilityTraitNotEnabled;

  [_accessibleElements addObject:stopElement];

  return_accessibleElements;
}
</code></pre>

<p>With the accessibileElements defined we need to implement three very simple access methods required by the UIAccessibilityContainer protocol. These methods provide an interface to our accessibileElements array:</p>

<pre><code>- (NSInteger)accessibilityElementCount
{
  return [[self accessibleElements] count];
}

- (id)accessibilityElementAtIndex:(NSInteger)index
{
    return [[self accessibleElements] objectAtIndex:index];
}

- (NSInteger)indexOfAccessibilityElement:(id)element
{
    return [[self accessibleElements] indexOfObject:element];
}
</code></pre>

<p>To ensure the UIAccessibilityContainer protocol and our newly defined accessibileElements take effect we need to ensure that the UYLCounterView does not itself respond to accessibility requests. To do that we need to implement the isAccessibilityElement for the custom view and ensure it returns NO:</p>

<pre><code>- (BOOL)isAccessibilityElement
{
  return NO;
}
</code></pre>

<p>We still have a few refinements to make but we already have enough of an implementation to make our custom view accessible. The Accessibility Inspector now gives us a result when we select the counter text as follows:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-22-001.png" alt="" /></p>

<h3>Updating the Counter Value</h3>

<p>When we created the UIAccessibilityElement for the counter text we set the accessibilityValue property to the current value of the counter. Since the counter is updated every second when the counter is running we need to ensure that we also update the accessibilityValue. We can easily do that in the setter for the secondsCounter value maintained by the UYLCounterView:</p>

<pre><code>- (void)setSecondsCounter:(NSUInteger)secondsCounter
{
  if (secondsCounter &gt; UYLCOUNTERVIEW_LIMIT)
  {
      secondsCounter = UYLCOUNTERVIEW_LIMIT;
  }

  _secondsCounter = secondsCounter;

  if (_accessibleElements)
  {
      UIAccessibilityElement *counterElement = [self.accessibleElements
        objectAtIndex:UYLCOUNTERVIEW_ELEMENTINDEX_COUNTERTEXT];
      counterElement.accessibilityValue = [[NSNumber
                                          numberWithInteger:secondsCounter]
                                          stringValueAsTime];
  }

  [self setNeedsDisplay];
}
</code></pre>

<p>Note that that accessibleElements array should only be allocated via the getter method we saw previously when VoiceOver is active. We therefore use the ivar to check if it has been allocated before attempting to access it. After retrieving the UIAccessibilityElement for the counter we then set the accessibilityValue using our NSNumber stringValueAsTime category method.</p>

<h3>Setting UIButton Traits</h3>

<p>The next refinement we need to make is to update the accessibility traits for the two UIButton controls. When the start button is used it disables itself and enables the stop button. We can update the accessibilityTraits of the corresponding UIAccessibilityElement in the method that is triggered by the UIButton action to indicate to VoiceOver which buttons are enabled:</p>

<pre><code>- (void)startAction:(UIButton *)sender
{
  ...
  ...

  if (_accessibleElements)
  {
      UIAccessibilityElement *startElement = [self.accessibleElements
                  objectAtIndex:UYLCOUNTERVIEW_ELEMENTINDEX_STARTBUTTON];
      startElement.accessibilityTraits = UIAccessibilityTraitButton |
                                         UIAccessibilityTraitNotEnabled;

      UIAccessibilityElement *stopElement = [self.accessibleElements
                    objectAtIndex:UYLCOUNTERVIEW_ELEMENTINDEX_STOPBUTTON];
      stopElement.accessibilityTraits = UIAccessibilityTraitButton;        
  }
  ...
  ...
}
</code></pre>

<p>Likewise when the stop button is used it disables itself so we also need to set the accessibility trait to indicate the new button state:</p>

<pre><code>- (void)stopAction:(UIButton *)sender
{
  ...

  if (_accessibleElements)
  {
      UIAccessibilityElement *stopElement = [self.accessibleElements
                   objectAtIndex:UYLCOUNTERVIEW_ELEMENTINDEX_STOPBUTTON];
      stopElement.accessibilityTraits = UIAccessibilityTraitButton |
                                        UIAccessibilityTraitNotEnabled;
  }
  ...
}
</code></pre>

<h3>Handling View Rotation</h3>

<p>I am not sure why but most accessibility example Apps do not support device orientation changes. I can only suspect that this is due to the extra complexity involved in dealing with the conversion between screen and view coordinate systems. The implementation of the accessibileElements getter in our UYLCounterView takes this conversion into account when calculating the accessibilityFrame for each element. This ensures that the frame is set correctly based on the device orientation at the time the getter is invoked. There is however a problem if the orientation changes once we have calculated the frame. Since we never recalculate these frames they will no longer be correct if the orientation changes. To illustrate the problem this is how the accessibilityFrame for the counter text appears if we rotate from portrait to landscape:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-22-002.png" alt="" /></p>

<p>To fix this problem we need to force the accessibility frames to be recalculated when the device orientation changes. The easiest way I have found to do that is to detect the orientation change in the view controller and force the accessibleElements array to be recreated. To detect the orientation change in the UYLTaskViewController we can implement the didRotateFromInterfaceOrientation method:</p>

<pre><code>- (void)didRotateFromInterfaceOrientation:
        (UIInterfaceOrientation)fromInterfaceOrientation
{
  self.taskCounterView.accessibleElements = nil;
}
</code></pre>

<p>Now the next time that the accessibleElements array is accessed it will be created from scratch and the frames that are created will be based on the new orientation. We can check that with the inspector with the simulator in landscape:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-04-22-003.png" alt="" /></p>

<h3>Notifications</h3>

<p>When I covered the creation of the UIAccessibilityElement for the text counter I mentioned that we were using the UIAccessibilityTraitUpdatesFrequently trait but I did not fully describe the effect that this achieves. To fully understand how VoiceOver works in this case you will need to build the example App and install it on a physical device. With the text element selected VoiceOver announces the changing timer value every few seconds. In this case that turns out to be a good choice as the value is changing too quickly for VoiceOver to keep up. In my testing I found that VoiceOver would announce a new value every 4-5 seconds. Note that a new announcement is only made when the value is actually changing so if the time is stopped the announcements also stop. If you take a look at how the StopWatch function within the Apple Clock App works you will find that it also uses a similar technique.</p>

<p>However if we wanted to force VoiceOver to announce every change to the counter view we can tell it that something has changed by posting a notification. The notifications used by VoiceOver are a little different from the usual iOS notifications. To create a notification you need to use a UIKit function named <strong>UIAccessibilityPostNotification</strong>. This function takes two parameters, the first to specify the notification type and the second an optional notification specific parameter which is usually nil.</p>

<p>To indicate that something on the screen has changed we have two choices for the notification type. The first possibility is to send a <strong>UIAccessibilityLayoutChangedNotification</strong> to indicate that one or more, but not all, elements on the screen have changed. The other possibility is to send a <strong>UIAccessibilityScreenChangedNotification</strong> to indicate that the whole screen has changed and VoiceOver should reset. In this case we are only changing the duration text so we could send the layout changed notification by inserting the following function call into the setter method setSecondsCounter:</p>

<pre><code>UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification,
                                nil);
</code></pre>

<p>To test this change I also removed the UIAccessibilityTraitUpdatesFrequently trait from the text element. When run on the device VoiceOver does indeed attempt to announce the value of the duration every time it changes. Of course since it takes longer than a second to announce the duration it quickly falls behind which is not very useful. So in this situation where the value of an element is changing faster than VoiceOver can announce the changes it is better to use the UIAccessibilityTraitUpdatesFrequently trait.</p>

<p>Whilst on the subject of notifications there is another option which can be useful when you need to make an announcement for an event that does not update the user interface. You can post a UIAccessibilityAnnouncementNotification which causes VoiceOver to announce the NSString that is passed as the second parameter:</p>

<pre><code>UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification,
                                @"Hello World");
</code></pre>

<h3>Wrapping Up</h3>

<p>This has been a long post but I hope that if you have made it this far I have convinced you that adding accessibility support to your App is not difficult. If you do not have custom views it is often trivial and requires minimal coding. Even if you do have custom views creating the necessary accessibility container elements is not much more effort. The key point to remember is that the accessibility frames need to be specified in screen coordinates.</p>

<p>The example App that I used for this post can be found <a href="http://useyourloaf.com/assets/code/TaskTimer.zip">here</a> or in my Github <a href="https://github.com/kharrison/CodeExamples/tree/master/TaskTimer">CodeExamples repository</a>. I hope you found this post useful and that it will encourage you to ensure your Apps play nice with VoiceOver.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Splitview controller is expected to have a master view controller]]></title>
    
      <category term="splitviewcontroller"/>
    
    <link href="http://useyourloaf.com/blog/2012/04/06/splitview-controller-is-expected-to-have-a-master-view-contr.html"/>
    <updated>2012-04-06T14:58:00+01:00</updated>
    <id>http://useyourloaf.com/blog/2012/04/06/splitview-controller-is-expected-to-have-a-master-view-contr</id>
    <content type="html"><![CDATA[<p>Whilst playing with the Master Detail Application template provided with Xcode 4.3.2 I came across an odd error message for the split view controller class. The problem happens when you implement the UISplitViewControllerDelegate method that specifies whether the master view controller should be hidden in a given orientation. The <em>splitViewController:shouldHideViewController:inOrientation</em> method was introduced in iOS 5.0 and is useful when you want to change the default behaviour which hides the master view in portrait mode. See this earlier post on <a href="http://useyourloaf.com/blog/2011/10/19/ios-5-split-view-controller-changes.html">iOS 5 split view controller changes</a> for the full details.</p>

<p>To reproduce the problem create a new project using the Master Detail Application template and implement the following method in the DetailViewController:</p>

<pre><code>- (BOOL)splitViewController:(UISplitViewController *)svc
   shouldHideViewController:(UIViewController *)vc
              inOrientation:(UIInterfaceOrientation)orientation {
  return YES;
}
</code></pre>

<p>Now when you run the project in the iPad Simulator you get the following error message logged to the console:</p>

<pre><code>Splitview controller &lt;UISplitViewController: 0xbec57e0&gt; is expected to have
a master view controller before its used!
</code></pre>

<p>Clearly an attempt to use a split view controller without giving it the two view controllers that it expects would be a serious error and probably deserves an immediate abort. However in this case we are using unmodified template code from Apple which does configure the split view controller with both a master and detail controller. The App also appears to run fine so the warning message does at first seem puzzling.</p>

<p>I noticed a while back that Apple changed the style of many of the example iOS projects to construct the initial root view controller interface in code rather than load it via a NIB file. The Master Detail application template also follows that trend. The following code snippet is from the point in the application delegate where the UISplitViewController is allocated and configured with its delegate and the two view controllers for the master and detail views:</p>

<pre><code>- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  ...
  ...
  self.splitViewController = [[UISplitViewController alloc] init];
  self.splitViewController.delegate = detailViewController;
  self.splitViewController.viewControllers = [NSArray
                           arrayWithObjects:masterNavigationController,
                           detailNavigationController, nil];
  ...
  ...
}
</code></pre>

<p>This looks fine but notice that the split view controller delegate is set before the viewControllers. This seems to be the source of the problem and if you reverse the two lines as shown below the warning message disappears:</p>

<pre><code>  self.splitViewController = [[UISplitViewController alloc] init];
  self.splitViewController.viewControllers = [NSArray
                           arrayWithObjects:masterNavigationController,
                           detailNavigationController, nil];
  self.splitViewController.delegate = detailViewController;
</code></pre>

<p>So it seems that the UISplitViewController performs some work in the setter for the delegate property and that this relies on the viewControllers already being set. I cannot find anything in the documentation that mentions this and it appears that whoever wrote the Xcode template was also unaware of this requirement.</p>

<p>In this case it does not seem to be a serious issue and the fix is trivial but if you come across this error message you may want to check if you have your viewControllers configured before you set the split view controller delegate. In the meantime I am thinking this is worth a bug report to Apple to see if they can provide some clarification in the UISplitViewController class documentation.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Updating for iPad retina display]]></title>
    
      <category term="iPad"/>
    
    <link href="http://useyourloaf.com/blog/2012/03/16/updating-for-ipad-retina-display.html"/>
    <updated>2012-03-16T22:15:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2012/03/16/updating-for-ipad-retina-display</id>
    <content type="html"><![CDATA[<p>Well today was the day that people started to get their hands on the third generation iPad with a double resolution retina display. Below are my notes on the minimal updates that you should consider making to best support all of those extra pixels.</p>

<h3>Custom Application Images</h3>

<p>Apple takes care of the UIKit images for standard iOS controls but if you have any custom images specific to the iPad you will as with the iPhone 4 need to supply @2x versions. I know many developers were sensibly preparing for this ahead of time by updating their iOS 5.0 built apps with double resolution images in the hope that they would just work on the new iPad. However there is one important caveat that can nicely summarised by this <a href="https://twitter.com/#!/Jury/status/180367953001324547">tweet</a> from Michael Jurewitz (@Jury):</p>

<pre><code>PSA - If you want your retina graphics to show up on the new iPad, you NEED
to build with Xcode 4.3.1 and __link against the 5.1 SDK__
</code></pre>

<h3>Application Icons</h3>

<p>The next most obvious update you need to do is provide a double resolution version of the main App icon. Apps that still only have a single resolution icon will stick out like a sore thumb on a retina display iPad.</p>

<p>There seems to be an a never-ending and growing list of dimensions that you need to supply for the application icon and the iPad retina display adds to that list. You should consult the <a href="https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/App-RelatedResources/App-RelatedResources.html#//apple_ref/doc/uid/TP40007072-CH6-SW1">iOS App Programming Guide</a> and <a href="https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1">iOS Human Interface Guidelines</a> for the comprehensive list but as a minimum you should at least include a new App icon and search results icon for the iPad retina display as follows:</p>

<h3>iPad App icon (144x144 pixels)</h3>

<p>The standard resolution main App icon for the iPad is 72x72 pixels. The retina display requires a @2x variant that is therefore 144x144 pixels.</p>

<h3>iPad Search results icon (100x100 pixels)</h3>

<p>The search results icon is used on the search results page and at standard resolutions is 50x50 pixels on the iPad. The @2x variant for the retina display version of the iPad is therefore 100x100 pixels.</p>

<h3>Filenames and Info.plist</h3>

<p>Depending on the level of backward compatibility that you need to maintain you may need to use specific naming conventions or add the new icon files to the application Info.plist file.</p>

<p>The most complicated situation is when you are dealing with a universal app that needs to maintain compatibility all the way back to iOS 3.1.x or earlier. In this case you will need to use very specific Icon filenames as the Info.plist keys were not used prior to iOS 3.2. The full list would now be something like this:</p>

<ul>
<li>Icon.png - 57x57 iPhone App Icon</li>
<li>Icon@2x.png - 114x114 iPhone retina display App Icon</li>
<li>Icon-72.png - 72x72 iPad App Icon</li>
<li>Icon-72@2x.png  - 144x144 iPad retina display App Icon</li>
<li>Icon-Small.png - 29x29 iPhone settings and search results icon</li>
<li>Icon-Small@2x.png - 58x58 iPhone retina display settings and search results icon</li>
<li>Icon-Small-50.png - 50x50 iPad search results icon</li>
<li>Icon-Small-50@2x.png - 100x100 iPad retina display search results icon</li>
</ul>


<p>Of course there is nothing to stop you using this naming convention for all of your apps but if you are targeting iOS 3.2 or later you can specify different filenames using the Info.plist file. The CFBundleIconFiles key was introduced with iOS 3.2 and allows you to directly list the names of the icon files. if you omit the filename extension (.png) you should be able to omit listing the @2x variants as the system should automatically detect the double resolution versions.</p>

<p>To further complicate things Apple introduced a new CFBundleIcons key in iOS 5.0 to support the Newsstand. This key contains a CFBundleIconFiles subkey which is an array of filenames which take precedence over the older CFBundleIconFiles key. If you are targeting iOS 5.0 and later you can switch to this key but if you need to support iOS 4.x or 3.2 you should also include the CFBundleIconFiles key.</p>

<p>All in all this is a bit of a mess and I would suggest that you test all of the various combinations you need to support carefully as it is easy to slip up.</p>

<h3>App Store Screenshots</h3>

<p>Apple recently changed the App Store submission rules for iPhone and iPod touch apps so that you have to submit screenshots for the retina display. The actual dimensions of the screenshot vary depending on whether you include space for the status bar or not but dimensions should be as follows (first value includes the status bar):</p>

<ul>
<li>Landscape: 960x640 or 960x600 pixels</li>
<li>Portrait: 640x960 to 640x920</li>
</ul>


<p>Apple has not, so far, placed a similar restriction on iPad screenshots but since you will want your screenshots to look good on the latest iPad it seems like a good time to switch to only retina sized screenshots for all devices.</p>

<p>The dimensions for a retina iPad screenshot are as follows (as before the first dimension includes the status bar):</p>

<ul>
<li>Landscape: 2048x1536 or 2048x1496 pixels</li>
<li>Portrait: 1536x2048 or 1536x2008 pixels</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git branch management with Xcode]]></title>
    
      <category term="git"/>
    
    <link href="http://useyourloaf.com/blog/2012/02/29/git-branch-management-with-xcode.html"/>
    <updated>2012-02-29T21:19:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2012/02/29/git-branch-management-with-xcode</id>
    <content type="html"><![CDATA[<p>Xcode has supported <a href="http://git-scm.com/">Git</a> for version control since version 4.0 but I generally prefer to perform my version control from the command-line. The only version control operation that I do sometimes perform with Xcode is visualising differences between file versions. Xcode does a pretty nice job of showing the two versions of a file side by side and highlighting the additions/deletions in a way that is a lot clearer than a command-line diff.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-000.png" alt="" /></p>

<p>The other version control operation that I suspect could sometimes benefit from some visual tools is the management of branches and in particular the merging of branches. Since Xcode has the ability to manage Git branches I thought I would take a look and share my experiences in this post.</p>

<h3>Creating a Branch</h3>

<p>For the purposes of this post I am going to use my CodeExamples repository and create a new branch to experiment with converting one of the example projects to ARC. The Xcode features for managing branches are (mostly) contained in the Repositories section of the Xcode Organizer.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-001.png" alt="" /></p>

<p>To create a new Git branch from the Xcode organizer you need to make sure that the Branches folder is selected in the left-hand Navigator pane. You should then see the Add Branch and Remove Branch buttons in the command bar at the bottom:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-002.png" alt="" /></p>

<p>When you select the Add Branch button you get a dialog box allowing you to name the branch and also to specify from which branch this new branch should be based. Since at this point we only have the master branch we will use that and name the new branch &#8220;ARC-Conversion&#8221;:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-003.png" alt="" /></p>

<p>For comparison to create this new branch from the command-line using the branch command:</p>

<pre><code>$ git branch ARC-Conversion
</code></pre>

<p>One thing to be aware of if you are using the command-line is that creating the branch will not also switch you to the new branch.</p>

<h3>Switching branches</h3>

<p>When we created the branch using Xcode we selected the checkbox to switch us to the new branch. The current branch is always displayed in the top right-hand corner of the Organizer window when the project directory is selected in the Navigator pane on the Organizer.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-005.png" alt="" /></p>

<p>To verify the current branch from the terminal use the branch command to list all of the branches. The current branch is indicated by the leading &#8220;*&#8221;:</p>

<pre><code>$ git branch
* ARC-Conversion
  master
</code></pre>

<p>If you want to switch between branches from within Xcode you can do that from the Organizer using the appropriately named &#8220;Switch Branch&#8221; icon in the bottom right corner (again ensure you have the project directory selected in the left-hand pane and not the Branches or Remotes folders):</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-004.png" alt="" /></p>

<p>This drops down a dialog box which allows you to select from the available branches. The command-line equivalent using the checkout command to switch to the master branch would be as follows:</p>

<pre><code>$ git checkout master
</code></pre>

<p>To switch back to our feature development branch:</p>

<pre><code>$ git checkout ARC-Conversion
</code></pre>

<p>One thing you need to be aware of if you are performing git version control from the command line with the project open in Xcode is that it does not always immediately spot when you have changed something. I find with the Organizer that you need to switch between some different views before it spots that the current branch has changed.</p>

<h3>Committing Changes</h3>

<p>For the purposes of this example I am going to generate some changes by converting this project to ARC. I will not cover that process and the results here as that is a topic for a separate post, for now it is sufficient that we have some changes to our project that we need to commit. The files that have been changed are visible in the Xcode Navigator pane (marked with &#8220;M&#8221; for modified):</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-006.png" alt="" /></p>

<p>You can also of course always check what has changed from the command-line (note that we are on the ARC-Conversion branch):</p>

<pre><code>$ git status
# On branch ARC-Conversion
# Changes not staged for commit:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#       modified:   Stepper.xcodeproj/project.pbxproj
#       modified:   Stepper/UYLAppDelegate.m
#       modified:   Stepper/UYLViewController.h
#       modified:   Stepper/UYLViewController.m
#no changes added to commit (use "git add" and/or "git commit -a")
</code></pre>

<p>To commit these changes to our new branch you can either use the Commit button in the Organizer or from the Xcode application menu use File > Source Control > Commit or if you can remember the keyboard shortcut simply type Option-Command-C.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-007.png" alt="" /></p>

<p>The commit window gives you a very nice overview of the files that will be included in this commit so that you can review the changes. If you really want to you can deselect some of the files from the commit, but all you really need to do is enter a commit message (always a good idea) and hit the commit button.</p>

<p>The command-line equivalent would be something like this:</p>

<pre><code>$ git commit -a -m "Converted to ARC"
[ARC-Conversion 7ec268a] Converted to ARC
 4 files changed, 6 insertions(+), 15 deletions(-)
</code></pre>

<h3>Merging Changes Back to Master</h3>

<p>Once you have completed development of the new feature (and of course tested everything) it needs to get merged back into the master branch. To do that you first need to switch back to the Master branch (using Xcode or from the command-line).</p>

<p>At this point things get a little bit confusing with Xcode as to merge the changes you need to switch back to the Xcode project window. There does not seem to be any way to perform the merge from the Xcode Organizer window. With the project window selected you can access the File > Source Control > Merge menu option. I find this a little annoying that the branching and merging commands cannot all be performed from the Organizer. Anyway once you find the Merge command you should see a dialog asking you to confirm which branch you want to merge back into the current (master) branch. Since we only have one branch in this example we just need to choose the ARC-Conversion branch:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-008.png" alt="" /></p>

<p>The Merge window looks very similar to the Commit window in that it allows you to view a diff of the changes but also importantly to select which branch to keep in the event that you have a conflict. In a real world situation it is possible that the master branch has also changed whilst we have been working on our great new feature. This may mean you need to keep the changes from one of the branches or maybe merge the two sets of changes manually.</p>

<p>The Xcode Merge window shows you each change along with an indicator showing which change is being preserved. In the screenshot below the master branch is on the left and the ARC-Conversion branch is on the right.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-009.png" alt="" /></p>

<p>The small indicator icon in the middle indicates that the change from the ARC-Conversion branch has been merged into the master branch version of the file. The icons at the bottom of the window allow you to change this and if required discard the change from our feature branch. Of course, you can also manually edit the master file at this point to resolve any conflicts.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-28-010.png" alt="" /></p>

<p>To merge the branch manually in the situation where the master branch has changes in a file:</p>

<pre><code>$ git merge ARC-ConversionAuto-merging Stepper/Stepper/UYLViewController.m
CONFLICT (content): Merge conflict in Stepper/Stepper/UYLViewController.m
Automatic merge failed; fix conflicts and then commit the result.
</code></pre>

<p>In this case we need to manually fix the conflict in the UYLViewController.m file and then tell git that we have resolved the conflict by adding the file back to the changes to be committed. We can then perform the commit to finish the merge:</p>

<pre><code>$ git add Stepper/Stepper/UYLViewController.m$ git commit 
  -m "Merge of ARC-Conversion branch"
</code></pre>

<h3>Deleting the Branch</h3>

<p>Now that all of the changes have been merged backed into the master branch we can clean up by deleting the feature branch. From the Xcode Repositories Organizer view this is as simple as selecting the branch and then using the Remove Branch icon.</p>

<p>Xcode will complain if you try to delete a branch that it thinks has not been merged. In playing with this feature I found that Xcode would get confused if I needed to manually resolve some conflicts and performed the final merge and commit from the command-line. To get Xcode to delete a branch without complaining it was necessary to perform an additional merge from within Xcode - which of course did nothing as all of the changes had already been merged.</p>

<p>Alternatively to delete the branch from the command-line:</p>

<pre><code>$ git branch -d ARC-Conversion
</code></pre>

<h3>Summary</h3>

<p>In playing with Xcode to perform branches and merges I have to say I really wanted to like the feature. I have always liked the way that Xcode visually displays code diffs and the ability to extend that capability to resolving conflicts during merges seems promising. I am assuming that a few of the minor glitches and bugs will get cleaned up but even so I think I will stick to the command-line for branching and merging. The command-line is always going to be faster once you get the commands stuck in your head and it just feels safer not to have Xcode acting as an intermediary. The visual tools are a nice bonus option to have though.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Updating to Xcode 4.3]]></title>
    
      <category term="Xcode"/>
    
    <link href="http://useyourloaf.com/blog/2012/02/17/updating-to-xcode-43.html"/>
    <updated>2012-02-17T23:10:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2012/02/17/updating-to-xcode-43</id>
    <content type="html"><![CDATA[<p>As if all the excitement of <a href="http://www.apple.com/macosx/mountain-lion/">Mountain Lion</a> was not enough for this week Apple has also pushed out Xcode 4.3. The big change is that Xcode is now a standard Mac App Store package which installs directly into the Applications directory. Previously when you installed from the App Store you rather confusingly downloaded an Xcode installer into the Applications directory which you then ran to install Xcode into /Developer.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-17-001.png" alt="" /></p>

<h3>Installing</h3>

<p>Xcode 4.3 is a free download from the <a href="http://itunes.apple.com/gb/app/xcode/id497799835?mt=12">Mac App Store</a> which, once it has downloaded, will install directly into the /Applications directory. You no longer even get an installation dialog offering you a choice of the installation directory though I guess there is nothing to stop you from moving it later. (Note that if you are developing for the iOS 5.1 beta release you should continue to use the Xcode 4.3 Developer preview available from the iOS Dev Center.)</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-17-002.png" alt="" /></p>

<p>Once the download is complete you should find Xcode installed in your /Applications folder just like any other App Store application. When you run Xcode for the first time you are prompted to remove the old version of Xcode that is in installed in /Developer (version 4.2.1 in my case) and also to delete the now redundant Xcode installer from /Applications:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-17-003.png" alt="" /></p>

<p>Of course if you want to maintain the older version for a while you are not forced to delete it right now you just need to manually drag the relevant files to the trash when you are ready.</p>

<p>As we have <a href="http://useyourloaf.com/blog/2012/01/10/xcode-42-building-for-ios-31x-and-older-devices.html">previously seen with Xcode 4.2</a> you need to download some optional components from the preferences if you want the iOS 4.3 Simulator or device debugging support for iOS versions prior to iOS 4.3. What has changed with Xcode 4.3 is that even the command-line tools are now an optional download:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-17-004.png" alt="" /></p>

<p>The interesting thing about the command line tools being a separate download is that it means they can now be installed without Xcode making life easier if you just want the compiler or OS X header files. The download link for the command line tools and a number of other optional tools that are now no longer bundled with Xcode can be found on the <a href="https://developer.apple.com/downloads/index.action?name=for%20Xcode%20-">Apple developer site</a>.</p>

<h3>/Developer Be Gone</h3>

<p>It is somewhat odd to be developing on a Mac that does not have a /Developer directory. One immediate impact of this will be on any scripts you have that rely on command-line tools that previously lived in /Developer. For example I often used the agvtool to <a href="http://useyourloaf.com/blog/2010/08/18/setting-iphone-application-build-versions.html">manage build version numbers</a> but if you try to run it after installing Xcode 4.3 you will get the following error message:</p>

<pre><code>$ agvtool
Error: No developer directory found at /Developer.
Run /usr/bin/xcode-select to update the developer directory path.
</code></pre>

<p>The xcode-select utility allows you to switch between versions of Xcode which makes it easy to correct the problem:</p>

<pre><code>$ sudo /usr/bin/xcode-select -switch /Applications/Xcode.app
</code></pre>

<p>If you are wondering where all of the files that were previously under /Developer have gone you can find them by right-clicking on the Xcode.app file in the Applications folder and showing the package contents. The old /Developer/usr/bin directory is now in /Applications/Xcode.app/Contents/Developer/usr/bin.</p>

<p>Don&#8217;t forget to clean up your shell environment if you previously referred to anything under /Developer. So for example, if you added /Developer/usr/bin to your PATH and /Developer/usr/share/man to your MANPATH you will need to prepend /Applications/Xcode.app/Contents to these settings in your shell login script.</p>

<h3>Where Did Instruments Go?</h3>

<p>One other side-effect of this reorganisation is that you can now no longer navigate with the Finder under /Developer to access some of the additional developer tools such as Instruments. To get around this you can launch them from the Xcode > Open Developer Tool menu or alternatively you will also find them by right-clicking on the Xcode icon in the dock. Of course, you can use Options > Keep in Dock from the dock icon of the running application if you want to keep the icon handy in the dock for future access.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Remote Packet Capture for iOS devices]]></title>
    
      <category term="network"/>
    
    <link href="http://useyourloaf.com/blog/2012/02/07/remote-packet-capture-for-ios-devices.html"/>
    <updated>2012-02-07T23:33:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2012/02/07/remote-packet-capture-for-ios-devices</id>
    <content type="html"><![CDATA[<p>I previously posted about using the <a href="http://useyourloaf.com/blog/2012/01/30/network-link-conditioner.html">Network Link Conditioner</a> to create realistic and &#8220;challenging&#8221; network conditions when testing iOS apps. In this post I want to highlight another useful network debugging tool which allows you capture network traffic from an iOS device.</p>

<h3>Remote Virtual Interfaces</h3>

<p>As with the Network Link Conditioner you need to use a host Mac computer to perform remote packet capture of an iOS device. The only other requirement is that the device be connected to the host computer via USB. No jailbreaking or hacking of your device is required to get this to work.</p>

<p>The basic technique is to create an OS X remote virtual network interface that represents the remote network stack of the iOS device. Once you have the virtual interface you can use your favourite network debugging tool such as tcpdump or wireshark to view the network traffic.</p>

<p>The steps to get the virtual network interface up and running are as follows:</p>

<ul>
<li>Plug your iOS device into the USB port of your Mac.</li>
<li>Use the Xcode organizer to obtain the UDID of the device (the value you want is named Identifier):</li>
</ul>


<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-07-001.png" alt="" /></p>

<ul>
<li><p>The remote virtual interface is created using the rvictl command, using the UDID you obtained in the previous step. The following command needs to be entered in the terminal window:</p>

<pre><code>  $ rvictl -s &lt;UDID&gt;
</code></pre></li>
</ul>


<p>If you want to capture packets from more devices you can repeat this process with the UDID for each device. You can also use the rvictl command to list the active devices:</p>

<pre><code>    $ rvictl -l
</code></pre>

<p>The virtual interfaces are named rvi0, rvi1, rvi2, etc. and like all network interfaces are viewable using the ifconfig command:</p>

<pre><code>    $ ifconfig rvi0
    rvi0: flags=3005&lt;UP,DEBUG,LINK0,LINK1&gt; mtu 0
</code></pre>

<p>Finally when you are finished you can remove the virtual interface:</p>

<pre><code>    $ rvictl -x &lt;UDID&gt;
</code></pre>

<h3>Using tcpdump</h3>

<p>The easiest way to capture and dump the network traffic is to use the tcpdump command which is included with OS X. The man page for tcpdump has lots of options but if you just want to see the live traffic the following will get you started:</p>

<pre><code>    $ tcpdump -n -i rvi0
</code></pre>

<p>To better illustrate the results I will use the <a href="http://useyourloaf.com/blog/2011/06/16/searching-twitter-with-ios.html">Twitter Search app</a> I showed in an earlier post to generate a simple http request and response.</p>

<pre><code>    $ tcpdump -n -t -i rvi0 -q tcp
    tcpdump: WARNING: rvi0: That device doesn't support promiscuous mode
    (BIOCPROMISC: Operation not supported on socket)
    tcpdump: WARNING: rvi0: no IPv4 address assigned
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on rvi0, link-type RAW (Raw IP), capture size 65535 bytes
    IP 192.168.1.66.55101 &gt; 192.168.1.64.51712: tcp 117
    IP 192.168.1.64.51712 &gt; 192.168.1.66.55101: tcp 0
    IP 192.168.1.64.51712 &gt; 192.168.1.66.55101: tcp 298
    IP 192.168.1.66.55101 &gt; 192.168.1.64.51712: tcp 0
    IP 192.168.1.66.55324 &gt; 199.59.148.201.80: tcp 0
    IP 199.59.148.201.80 &gt; 192.168.1.66.55324: tcp 0
    IP 192.168.1.66.55324 &gt; 199.59.148.201.80: tcp 0
    IP 192.168.1.66.55324 &gt; 199.59.148.201.80: tcp 269
    IP 199.59.148.201.80 &gt; 192.168.1.66.55324: tcp 0
    IP 199.59.148.201.80 &gt; 192.168.1.66.55324: tcp 1428
    IP 199.59.148.201.80 &gt; 192.168.1.66.55324: tcp 1428
    IP 199.59.148.201.80 &gt; 192.168.1.66.55324: tcp 1428 
</code></pre>

<p>Note the tcpdump options I am using to cut down some of the noise. The -t option gets rid of the timestamp on each line, -q removes some of the packet header information which is not interesting and finally we specify that we are only interested in TCP/IP packets.</p>

<p>My local IP address is 192.168.1.66 and the IP of the remote Twitter server in this case is 199.59.148.201. The http request starts on line 5 where you can see an outgoing connection to port 80:</p>

<pre><code>    IP 192.168.1.66.55324 &gt; 199.59.148.201.80: tcp 0
</code></pre>

<p>The following lines show the search results coming back. Of course, this trace is not very interesting as we cannot see the contents. You can add -x to the tcpdump command to see the actual packet contents but even that is not always that informative as you need to know how to decode and interpret the packet data. A quick and dirty way if you know you are dealing with http traffic is to add the -A option to get tcpdump to print the packet data in ASCII:</p>

<pre><code>    $ tcpdump -n -t -i rvi0 -q -A tcp
    ...
    GET /search.json?rpp=100&amp;q=apple HTTP/1.1
    Host: search.twitter.com
    User-Agent: TwitterSearch/1.0 CFNetwork/548.0.4 Darwin/11.0.0
    Accept: */*
    Accept-Language: en-us
    Accept-Encoding: gzip, deflate
    Cookie: k=86.168.77.194.5802087337bc706b
    Connection: keep-alive
    ...
    HTTP/1.1 200 OK
    Cache-Control: max-age=15, must-revalidate, max-age=300
    Expires: Tue, 07 Feb 2012 22:18:05 GMT
    Content-Type: application/json;charset=utf-8
    Vary: Accept-Encoding
    Date: Tue, 07 Feb 2012 22:13:06 GMT
    X-Varnish: 682230572
    Age: 0
    Via: 1.1 varnish
    Server: tfe
    Content-Encoding: gzip
    Content-Length: 12715 
</code></pre>

<p>This is a minor improvement in that we can now see the HTTP GET request with the query we are using and see the HTTP response but we still cannot easily drop down into the JSON in the result to see what Twitter is sending back. For that we need to use a more sophisticated tool than tcpdump.</p>

<h3>Using Wireshark</h3>

<p>Whilst tcpdump is a quick and easy way to see and capture traffic it is not exactly an easy tool to use when you want to figure out what is going on. <a href="http://www.wireshark.org/">Wireshark</a> is a much easier tool if you want perform deeper packet inspection or if you just prefer your network debugging tools to have a user interface. Luckily Mac OS X ports are readily available, if you are following along I downloaded and installed version 1.6.5 for OS X 10.6 (Snow Leopard) Intel 64-bit from <a href="http://www.wireshark.org/download.html">here</a>.</p>

<p>Once you have Wireshark installed and running you should see a list of available interfaces that it can capture. The one we are interested in is of course our virtual interface rvi0:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-07-002.png" alt="" /></p>

<p>Selecting rvi0 switches us to a live capture of the packet data with a lot more information to help us decode and understand what is going on. This can be interesting to watch and see all of the things your iOS device is doing. For the purposes of this example it is useful to apply some filters so we can focus in on the HTTP request traffic. The easiest way to do that is to apply a display filter (Analyze -> Display Filters&#8230;). There are a number of pre-defined filter expressions including being able to limit the display to HTTP traffic:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-07-003.png" alt="" /></p>

<p>Now if create our request it is immediately obvious what is going on as we can clearly see the HTTP GET request and the JSON response:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-07-004.png" alt="" /></p>

<p>The central pane of wireshark allows you to drill down into the contents of each packet allowing us to see the JSON details:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-02-07-005.png" alt="" /></p>

<p>The full packet decode is also available in the lower pane if you need to see the whole packet.</p>

<h3>Wrapping Up</h3>

<p>I should say that this post is not an attempt to explain everything involved in debugging network communications using tcpdump or wireshark. That is a huge topic and requires some knowledge of the underlying protocols. What I did want to make clear is that the tools you need to capture and analyse live traffic off your iOS device are readily available and take just a few minutes to get setup. It is not something you will (hopefully) need to use every day but it is well worth having it in your toolbox for those occasions when you need to debug network communications.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Network Link Conditioner]]></title>
    
      <category term="network"/>
    
    <link href="http://useyourloaf.com/blog/2012/01/30/network-link-conditioner.html"/>
    <updated>2012-01-30T23:38:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2012/01/30/network-link-conditioner</id>
    <content type="html"><![CDATA[<p>The Network Link Conditioner (NLC) tool is an extremely useful tool introduced with Lion that allows you to test how well an application behaves when subject to various network conditions. Whilst it is an OS X tool that runs on a Mac it can still be used test iOS apps that are running in the iOS Simulator. In this post I will show some examples of how to use the tool to test an iOS app and verify how it well it handles various network error conditions.</p>

<h3>Getting Up and Running</h3>

<p>With Xcode installed on Lion you should find the NLC tool installed in <code>/Developer/Applications/Utilities/Network Link Conditioner/</code>. It is actually implemented as a System Preferences Pane which you can install with a double-click. The Xcode 4.2 release notes mention a limitation that you need to reboot before the NLC daemon will run or you can manually reload with the following command:</p>

<pre><code>$ sudo launchctl load 
  /system/library/launchdaemons/com.apple.networklinkconditioner.plist
</code></pre>

<p>Once installed you should find the Network Link Conditioner icon in the &#8220;Other&#8221; section of the System Preferences pane:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-30-001.png" alt="" /></p>

<p>The User Interface is pretty simple, consisting of a master on/off switch, a list of pre-defined profiles and a manage profiles button to create your own profiles. Note that the NLC tool applies to the network interface of your Mac so it will impact ALL traffic on your computer when you turn it on. So you probably want to avoid doing anything else that is relying on a network connection whilst you are testing.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-30-002.png" alt="" /></p>

<h3>Creating Test Profiles</h3>

<p>The NLC can be used limit bandwidth, add delays both to normal traffic and to DNS queries and create packet loss. It comes pre-configured with a number of typical network profiles to allow you to simulate common 3G cellular, cable modem, DSL and WiFi connections. For testing purposes I created three rather extreme network conditions as follows:</p>

<h4>Slow Net - Very Limited Bandwidth</h4>

<p>This profile severely limits the bandwidth by setting both the Downlink and Uplink Bandwidth to 32kbps. A 100ms delay is also added to packets in each direction and for good measure there is also a 200ms delay to DNS queries.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-30-003.png" alt="" /></p>

<p>This configuration is useful for slowing down all network communication so that you can really see what your app is doing. This helps flush out any points in your code where you have network code blocking the main thread. It can also help you see any progress bars or temporary spinning activity indicators that might otherwise only be displayed for a split second when testing on a fast network.</p>

<h4>Nasty Net - High Packet Loss</h4>

<p>This network profile increases the pain levels even further by dropping 90% of all packets in each direction:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-30-004.png" alt="" /></p>

<h4>Black Hole - 100% Downlink Packet Loss</h4>

<p>Finally I have a network profile which simply drops ALL downlink packets. This is useful for testing network timeout conditions. Try starting with Slow Net and switching to Black Hole once your network traffic gets underway if you really want to be mean&#8230;.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-30-005.png" alt="" /></p>

<h3>Putting an App to the Test</h3>

<p>So to try things out I will run the <a href="http://useyourloaf.com/blog/2011/06/16/searching-twitter-with-ios.html">Twitter Search</a> app that I used to explore NSURLConnection in the iOS Simulator. If you are interested in the code under test refer back to that earlier post for details. The app takes a single string and then uses NSURLConnection to query the Twitter search API and display the results in a table view. Normally when run in the iOS Simulator the results are displayed in under a second which makes it hard to see what is happening. If I turn on the Slow Net profile though the query takes 5-10 seconds making it a lot easier to verify how the app behaves.</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-30-006.png" alt="" /></p>

<p>Since we are using an NSURLConnection the actual network connection happens asynchronously, the user interface is not blocked and our table view, displaying a Loading&#8230; message responds to touches. In addition we can see that the network activity spinner has been activated (more on this in a moment) to inform the user that we accessing the network.</p>

<p>To further test what happens when our network connection fails we will switch to the Black Hole profile which will prevent all responses from reaching our app. Now if we wait long enough the network connection should time out and we can test how well we cope with that situation. Our application implements the connection:didFailWithError: delegate method of NSURLConnection to display the error message and we should also see our status message in the first row of the table update to indicate that the service is not available. Sure enough after about a minute the connection times out and the user interface responds correctly:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-30-007.png" alt="" /></p>

<p>This is all very good but whilst playing around with this app I actually spotted some unintended behaviour (ok that is another way of saying a bug&#8230;). With either the Slow Net or the Nasty Net profile enabled it is very easy to reproduce. As I mentioned previously whilst we are waiting for the search query to complete so we can display the results the user interface is not blocked. This means that the user can hit the Search button in the Navigation bar to return to the initial screen. When they do that the NSURLConnection is still running and the network activity indicator is still active. Now it will eventually time out and clean itself up but there is nothing to stop the user from initiating another search before the old one has timed out. That is certainly not what I intended when I wrote the app but I never really considered this situation. The fix is easy if we implement the viewWillDisappear method in our view controller and use that to cancel the connection:</p>

<pre><code>- (void)viewWillDisappear:(BOOL)animated
{
   [self cancelConnection];
}
</code></pre>

<p>The cancelConnection method takes care of cleaning things up for us:</p>

<pre><code>- (void)cancelConnection
{
   if (self.connection != nil)
  {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [self.connection cancel];
    self.connection = nil;
    self.buffer = nil;
  }
}
</code></pre>

<p>Now when we exit the search results table view controller any running connection is cancelled, the network activity spinner is stopped and the temporary buffer is cleaned up.</p>

<h3>Wrapping Up</h3>

<p>When I started out to write this post I was already sure that testing applications under challenging network conditions was a good idea. However I guess the fact that I actually also found an error in some previously posted code further demonstrates the point. You can find the updated code in my github <a href="https://github.com/kharrison/CodeExamples/tree/master/TwitterSearch">CodeExamples</a> repository.</p>

<p>One final note, don&#8217;t forget to turn NLC off when your done or you may find your Github commits take a bit longer than expected&#8230;.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Core Data Queries Using Expressions]]></title>
    
      <category term="core data"/>
    
    <link href="http://useyourloaf.com/blog/2012/01/19/core-data-queries-using-expressions.html"/>
    <updated>2012-01-19T22:15:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2012/01/19/core-data-queries-using-expressions</id>
    <content type="html"><![CDATA[<p>Core Data can have a steep learning curve for anybody new to either the Mac or iOS platforms. One of the key points for me was understanding that Core Data is not a relational database but a persistent object store with many features to manage the life-cycle of an object. I think some of the confusion comes from the fact the Core Data can use SQLite as the underlying object store but that is an implementation detail that can lead you astray if you are not careful.</p>

<p>So if Core Data is not a relational database how do you do those things that would be easy if you could just use an SQL query? A Core Data fetch request with a combination of predicates and sort descriptors is a very flexible mechanism that covers many of the most common queries you might need for retrieving objects. However when you are more interested in querying for specific values such as the minimum or maximum value of an attribute an alternative approach using expressions can be easier and more efficient.</p>

<p>To illustrate the code snippets in this post I will assume a very simple Core Data model with a single entity to represent a task in a todo list:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-19-001.png" alt="" /></p>

<h3>Retrieving the minimum value of an attribute</h3>

<p>Each task object contains an NSDate attribute which indicates when the task was first created:</p>

<pre><code>@property (nonatomic, retain) NSDate * createdAt;
</code></pre>

<p>Suppose I want to find out what the oldest creation date is for all of the tasks. A first approach might be to use a fetch request to retrieve the first task after sorting all of the tasks by the creation date (with an ascending sort order):</p>

<pre><code>NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task"
                     inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchLimit:1];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
                                     initWithKey:@"createdAt"
                                     ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

NSError *error = nil;
NSArray *fetchResults = [self.managedObjectContext
                         executeFetchRequest:fetchRequest
                         error:&amp;error];

Task *oldest = [fetchResults lastObject];
NSLog(@"oldest = %@",oldest.createdAt);
</code></pre>

<p>Note that the fetch limit (setFetchLimit) is set to 1 as we only want the first object in the sorted list of all tasks. This is not a bad solution but as we will see we can do much better. To understand what Core Data is doing under the covers it can be very useful to turn on some debugging. In particular we can get Core Data to show us the underlying SQL queries it is using by setting the argument -com.apple.CoreData.SQLDebug to 1 on application launch. With Xcode 4 the launch arguments are set in the project scheme window:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-19-002.png" alt="" /></p>

<p>With the debugging enabled we can see the query that Core Data is using and the fetch execution time which will be useful when comparing the performance of different approaches:</p>

<pre><code>2012-01-19 20:31:37.864 ToDoSync[3455:fb03] CoreData: sql: SELECT 0,
t0.Z_PK, t0.Z_OPT, t0.ZCOMPLETE, t0.ZCREATEDAT, t0.ZNOTE, t0.ZTITLE FROM
ZTASK t0 ORDER BY t0.ZCREATEDAT LIMIT 1
2012-01-19 20:31:37.875 ToDoSync[3455:fb03] CoreData: annotation: sql
connection fetch time: 0.0742s
2012-01-19 20:31:37.875 ToDoSync[3455:fb03] CoreData: annotation: total
fetch execution time: 0.0784s for 1 rows.
</code></pre>

<p>The debugging output shows us that Core Data is performing a select to retrieve all of the attributes of the task object, ordered by creation data with a query limit of 1. The total fetch execution time in this case was 0.0784s based on a database containing 5,000 tasks running on a fourth generation iPod touch test device. Note that any time you are looking to optimise performance it is a good advice to run the code on an actual device. Running on the iOS Simulator will give you much faster performance due to the obviously greater performance of the host computer.</p>

<h3>Restricting The Properties to Fetch</h3>

<p>Before looking at the use of expressions there is one minor optimisation that we could consider applying to the previous fetch request. Since we are interested only in the creation date we can modify the fetch request to make it only retrieve that one property:</p>

<pre><code>[fetchRequest setResultType:NSDictionaryResultType]; 
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:@"createdAt"]];
</code></pre>

<p>By default the result type of a fetch request is NSManagedObjectResultType which as the name implies means we will get managed objects back from the fetch. To specify that we want one or more properties of an object you first need to make the fetch request return a dictionary by setting the result type to NSDictionaryResultType and then you set the properties to fetch by passing it an array containing the names of the properties you want back. In this case we just want the &#8220;createdAt&#8221; property. Now when we execute the fetch request we get back an array containing a single dictionary (since we set a fetch limit of 1) which contains the single property which in this case is an NSDate:</p>

<pre><code>NSDate *oldest = [[fetchResults lastObject] valueForKey:@"createdAt"] 
</code></pre>

<p>Looking at the SQL debug you can see that the select statement now only retrieves the single attribute</p>

<pre><code>2012-01-19 20:59:26.484 ToDoSync[18564:707] CoreData: sql: SELECT
t0.ZCREATEDAT FROM ZTASK t0 ORDER BY t0.ZCREATEDAT LIMIT 1
2012-01-19 20:59:26.535 ToDoSync[18564:707] CoreData: annotation: sql
connection fetch time: 0.0505s
2012-01-19 20:59:26.539 ToDoSync[18564:707] CoreData: annotation: total
fetch execution time: 0.0545s for 1 rows.
</code></pre>

<p>There is a performance improvement in that this fetch executes in around 0.05s compared to 0.07s for the previous example. However this may often turn out to be a false optimisation if after determining the earliest creation date we then shortly afterwards find we want to retrieve the actual task with this creation date. In that case it is generally better to just retrieve the full task as in the original query so that Core Data already has it cached ready for when we need it.</p>

<h3>Using an Expression</h3>

<p>A better way to solve this type of query is actually to create an expression with the function that we want to perform. Unfortunately there is a little bit more code required though we start as with the previous example by constructing a fetch request that will return a dictionary result:</p>

<pre><code>NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task"
                        inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setResultType:NSDictionaryResultType];
</code></pre>

<p>We then create an expression which specifies the function we want to use and the key-path of the property we want to apply it to. So for our example where we want the minimum of the createdAt property:</p>

<pre><code>NSExpression *keyPathExpression = [NSExpression
              expressionForKeyPath:@"createdAt"];
NSExpression *earliestExpression = [NSExpression 
              expressionForFunction:@"min:"
              arguments:[NSArray arrayWithObject:keyPathExpression]];
</code></pre>

<p>There are a wide range of functions that we could apply including average:, sum:, min:, max:, median:, sqrt:, etc., for the full list check the documentation for the NSExpression class. Unfortunately that is not all we need to do as we must also create an expression description to specify the result type we are expecting from the fetch request:</p>

<pre><code>NSExpressionDescription *earliestExpressionDescription =
                         [[NSExpressionDescription alloc] init];
[earliestExpressionDescription setName:@"earliestDate"];
[earliestExpressionDescription setExpression:earliestExpression];
[earliestExpressionDescription setExpressionResultType:NSDateAttributeType];
</code></pre>

<p>The key point is that we need to set a name for the expression which we will use when retrieving the result - remember that we have already specified that the fetch request should give us back a dictionary containing the result. The name of the expression will be our key into that dictionary. We also need to specify that we expect the result type of the expression to be an NSDate object. Finally we can set the properties to fetch using our expression description and execute the fetch request:</p>

<pre><code>[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:
                                    earliestExpressionDescription]];
NSError *error = nil;
NSArray *fetchResults = [self.managedObjectContext
                         executeFetchRequest:fetchRequest
                         error:&amp;error];
</code></pre>

<p>The NSArray we get back as the fetch result should contain a single NSDictionary object which contains the NSDate object stored using the expression description name as the key:</p>

<pre><code>NSDate *oldest = [[fetchResults lastObject] valueForKey:@"earliestDate"]; 
</code></pre>

<p>Finally just for completeness and assuming you are not using ARC we should release a few things:</p>

<pre><code>[earliestExpressionDescription release];
[fetchRequest release];
</code></pre>

<p>This is a lot more code than the original solution but the SQL debug log shows some interesting results:</p>

<pre><code>2012-01-19 21:47:39.292 ToDoSync[18639:707] CoreData: sql: SELECT
min( t0.ZCREATEDAT) FROM ZTASK t0
2012-01-19 21:47:39.304 ToDoSync[18639:707] CoreData: annotation: sql
connection fetch time: 0.0121s
2012-01-19 21:47:39.308 ToDoSync[18639:707] CoreData: annotation: total
fetch execution time: 0.0162s for 1 rows.
</code></pre>

<p>I find it somewhat amusing that the more code we write the smaller the underlying Core Data SQLite query gets :-) This fetch request, executed on the same device and dataset as before, executes in 0.0162s which is considerably faster than the original query which took over 0.07s. The reason is obvious if you take a look at the SQL query being used as Core Data is using SQLite to perform the min function directly on the createdAt property in the database avoiding the need to retrieve all 5,000 values.</p>

<p>Where expressions really start to become effective is when you need to perform multiple calculations on the same dataset. So suppose that we want to calculate both the earliest and the latest creation dates. All we need to do is construct a second expression:</p>

<pre><code>NSExpression *latestExpression =
              [NSExpression expressionForFunction:@"max:"
               arguments:[NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *latestExpressionDescription =
                        [[NSExpressionDescription alloc] init];
[latestExpressionDescription setName:@"latestDate"];
[latestExpressionDescription setExpression:latestExpression];
[latestExpressionDescription setExpressionResultType:NSDateAttributeType];
</code></pre>

<p>This time we are using the max: function and we have named our expression &#8220;latestDate&#8221;. Note that we do not need to use a separate fetch request for each of these expressions. We can set our properties to fetch to include both expressions and execute a single fetch request:</p>

<pre><code>[fetchRequest setPropertiesToFetch:[NSArray 
              arrayWithObjects:earliestExpressionDescription,
              latestExpressionDescription, nil]];
</code></pre>

<p>Now when we execute the fetch request we get back a dictionary containing two entries representing both the earliestDate and latestDate results:</p>

<pre><code>NSError *error = nil;
NSArray *fetchResults = [self.managedObjectContext
                         executeFetchRequest:fetchRequest
                         error:&amp;error];
NSDate *oldest = [[fetchResults lastObject] valueForKey:@"earliestDate"];
NSDate *latest = [[fetchResults lastObject] valueForKey:@"latestDate"];
</code></pre>

<p>As the SQL debug shows us this query to calculate both the earliest and latest dates executes almost as fast as the fetch for just the earliest date and is still many times faster than the original approach of sorting the property with Core Data:</p>

<pre><code>2012-01-19 22:06:33.153 ToDoSync[18681:707] CoreData: sql: SELECT
min( t0.ZCREATEDAT), max( t0.ZCREATEDAT) FROM ZTASK t0
2012-01-19 22:06:33.170 ToDoSync[18681:707] CoreData: annotation: sql
connection fetch time: 0.0174s
2012-01-19 22:06:33.175 ToDoSync[18681:707] CoreData: annotation: total
fetch execution time: 0.0220s for 1 rows.
</code></pre>

<h3>Wrapping Up</h3>

<p>Using NSExpression is perhaps not the most intuitive way to perform complex queries and calculations on Core Data sets. However I think it is worth spending some time mastering them as the performance improvements can be significant, especially when you need to frequently repeat a calculation with a large data set.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Xcode 4.2 building for iOS 3.1.x and older devices]]></title>
    
      <category term="Xcode"/>
    
    <link href="http://useyourloaf.com/blog/2012/01/10/xcode-42-building-for-ios-31x-and-older-devices.html"/>
    <updated>2012-01-10T22:44:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2012/01/10/xcode-42-building-for-ios-31x-and-older-devices</id>
    <content type="html"><![CDATA[<p>the extra effort it takes to maintain backward compatibility with iOS 3.1.x is getting a little greater with each update to Xcode and iOS. The release of Xcode 4.2 and iOS 5 added a couple of extra hurdles if you want to support older devices and pre-iOS 4.2 releases.</p>

<h3>Xcode iOS Simulator and Debugging Support</h3>

<p>When Apple released iOS 5 and Xcode 4.2 they removed iOS Simulator support for iOS versions prior to iOS 4.3. If you upgraded from an earlier version of Xcode you may not have noticed but they also made the iOS 4.3 simulator an optional download. If you do not see the iOS 4.3 simulator in the run destination popup you need to use the More Simulators option to download it.</p>

<p>Since the simulator no longer supports iOS versions prior to iOS 4.3 the only way to test apps on those earlier releases is to test on a device. That assumes of course that you still have a device running the iOS 3.1, 4.1 or 4.2 release that you need.</p>

<p>There is an additional step required if you are targeting iOS 3.1 or iOS 4.1 devices in that you also need to download the device debugging support. There are separate installs for iOS 4.x and iOS 3.x devices. When you plug in a development device running a pre-iOS 4.2 version you get prompted to download the appropriate package:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-10-001.png" alt="" /></p>

<p>You can also check and install the packages from the Downloads tab of the Xcode preferences:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-10-002.png" alt="" /></p>

<h3>Building for armv6 Devices</h3>

<p>Having got all the optional Xcode support files downloaded you may think you are done but if you build and run on older armv6 devices you may still hit a problem. Typically the build succeeds but fails to launch on the device. The problem is with older armv6 devices such as the second generation iPod touch and the iPhone 3G.</p>

<p>The default for iOS is now armv7 - otherwise referred to as <code>$(ARCHS_STANDARD_32_BIT)</code>. To build for the older devices you need to add armv6 to the Architectures build setting. The default in Xcode 4.2 is now as shown below:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-10-003.png" alt="" /></p>

<p>To add armv6 select the existing architecture setting and then using &#8220;Other&#8230;&#8221; to bring up the dialog and add an entry with the value &#8220;armv6 armv7&#8221; to return to building the &#8220;fat&#8221; binary. Ensure you do this for each target in the project. The setting should look as follows once you are done:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-10-004.png" alt="" /></p>

<p>Now you should finally be able to build and run on pre iOS 4.2 devices.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[UIStepper control]]></title>
    
      <category term="UIKit"/>
    
    <link href="http://useyourloaf.com/blog/2012/01/04/uistepper-control.html"/>
    <updated>2012-01-04T21:07:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2012/01/04/uistepper-control</id>
    <content type="html"><![CDATA[<p>A quick and simple post to kick off the new year looking at another cool iOS 5 UIKit addition. The UIStepper class provides a simple means to increment and decrement a value. You can get the idea from the screenshot below which illustrates how the control works:</p>

<p><img src="http://useyourloaf.com/assets/images/2012/2012-01-04-001.png" alt="" /></p>

<p>The UIStepper is a bit like a UISwitch or UISegmentedControl in appearance except that it consists of +/- symbols that increment/decrement an internal value. If you hook the value changed event to a target method you can then retrieve the value and use it to update another user interface element such as a UILabel to display the current value:</p>

<pre><code>- (IBAction)stepperChanged:(UIStepper *)sender {
  NSUInteger value = sender.value;
  self.counter.text = [NSString stringWithFormat:@"%03d",value];
}
</code></pre>

<p>By default, the UIStepper has a minimumValue of 0 and a maximumValue of 100 (both properties are of type double) and a stepValue of 1 which means the value increments/decrements by 1 each time the +/- symbols are touched. By default the increment/decrement action is also set to autorepeat which means that the value auto decrements/increments as long as the control is pressed. This being Apple there is the usual attention to detail so the stepper smoothly accelerates the longer you press the control.</p>

<p>Another useful property allows you to control whether the value wraps when it reaches the minimum or maximum values. By default the wraps property is set to NO. The final property, continuous, controls whether the value changes are sent immediately or only when the user touch action ends. By default this property is set to YES so you get each value change immediately.</p>

<p>You can of course change all of these defaults by setting the appropriate property on the UIStepper object:</p>

<pre><code>self.stepper.wraps = YES;
self.stepper.autorepeat = YES;
self.stepper.continuous = YES;

self.stepper.minimumValue = 0;
self.stepper.maximumValue = 100;
self.stepper.stepValue = 1;
</code></pre>

<p>There is very little code to share but if you want to play with the UIStepper control you can find the example code in my <a href="https://github.com/kharrison/CodeExamples">Github Code Examples</a> repository.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[UIAlertView changes in iOS 5]]></title>
    
      <category term="Alert"/>
    
      <category term="UIKit"/>
    
    <link href="http://useyourloaf.com/blog/2011/12/14/uialertview-changes-in-ios-5.html"/>
    <updated>2011-12-14T21:27:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2011/12/14/uialertview-changes-in-ios-5</id>
    <content type="html"><![CDATA[<p><em>The UIAlertView class has been available since iOS 2. It is similar to the UIActionSheet class but generally the UIAlertView is used to display an alert message to the user whereas UIActionSheet is useful when you want the user to confirm or choose between a set of options. This post will look at some useful additions to UIAlertView in iOS 5 however that also permit the user to enter some text into the alert view.</em></p>

<h3>The Default Style</h3>

<p>Before we look at what has changed in iOS 5 it is probably worth a quick recap of how UIAlertView worked in iOS 4. In all of these examples I will use an alert view with two buttons, a cancel button and an OK button. The code to create and show a basic UIAlertView is as follows:</p>

<pre><code>UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"DefaultStyle"
                           message:@"the default alert view style"
                           delegate:self
                           cancelButtonTitle:@"Cancel"
                           otherButtonTitles:@"OK", nil]; 
[alertView show];
</code></pre>

<p>The initialiser is fairly self-explanatory, it takes a title and a longer description text message which is displayed in the body of the alert view. The delegate is optional and for simple alerts can be set to nil. As I will show in a moment the delegate is required if you want to interact with the alert view for example to find out which button the user pressed.</p>

<p>The cancelButtonTitle may be nil if you do not want a cancel button otherwise it is set to the text to display in the cancel button. Finally there is a nil-terminated list of titles for additional buttons to show in the alert. In this case we just add an OK button. The appearance of the alert view is shown below:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-12-14-001.png" alt="" /></p>

<p>The view is dismissed by pressing either the Cancel or OK buttons. If you want to know which button the user pressed you need to implement some methods from the UIAlertViewDelegate. First we make our view controller adopt the delegate protocol:</p>

<pre><code>@interface UYLViewController : UIViewController &lt;UIAlertViewDelegate&gt;
</code></pre>

<p>Then in the view controller we implement alertView:didDismissWithButtonIndex as follows:</p>

<pre><code>- (void)alertView:(UIAlertView *)alertView
        didDismissWithButtonIndex:(NSInteger)buttonIndex
{
  NSLog(@"Alert View dismissed with button at index %d",buttonIndex);
}
</code></pre>

<p>The buttonIndex tells us which button was pressed to dismiss the view. The index starts at 0 so in our example with two buttons the Cancel button will give a value of 0 and the OK button will give 1. Of course you will probably want to do something more useful than log the result in a real application.</p>

<h3>Plain Text Input</h3>

<p>With iOS 5 the UIKit framework has added UIAlertView styles that allow for user input directly into the alert view. This is useful when you need to get a small amount of text input from the user such as a username or password before performing a task. The most simple style is to allow plain text input. The code to create and show a plain text input style alert view is as follows:</p>

<pre><code>UIAlertView *alertView = [[UIAlertView alloc]
                           initWithTitle:@"PlainTextStyle"
                           message:@"Enter plain text"
                           delegate:self
                           cancelButtonTitle:@"Cancel"
                           otherButtonTitles:@"OK", nil];

alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
[alertView show];
</code></pre>

<p>This is similar to creating the default alert view with the exception that we are setting the alertViewStyle property. This property is new in iOS 5 and takes a UIAlertViewStyle to set the style of the alert view. In this case we use UIAlertViewStylePlainTextInput which results in an alert view that looks like this:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-12-14-002.png" alt="" /></p>

<p>The display and dismissal of the keyboard is handled for you to allow the user to enter text into the text field. You can access the text that the user has entered from the delegate we previously used to determine which button was pressed:</p>

<pre><code>UITextField *textField = [alertView textFieldAtIndex:0];
NSLog(@"Plain text input: %@",textField.text);
</code></pre>

<p>Note that the text field is accessed via an instance method, textFieldAtIndex, which as the name suggests takes the index of the text field we want. The UIAlertViewStylePlainTextInput alert style contains a single text field at index 0.</p>

<h3>Secure Text Input</h3>

<p>The plain text input style is obviously not great if the input you want from the user is a password. Typically when entering a password iOS masks characters as they are typed. To get that style of user input we can use the UIAlertViewStyleSecureTextInput:</p>

<pre><code>alertView.alertViewStyle = UIAlertViewStyleSecureTextInput;
</code></pre>

<p>The resulting UIAlertView looks the same as the plain text version with the exception that characters are masked a few seconds after they are entered:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-12-14-003.png" alt="" /></p>

<h3>Login and Password Input</h3>

<p>The final style covers the situation where you want to get both a username and a password in a single alert view. The UIAlertViewStyleLoginAndPasswordInput style gives us an alert view that looks as follows:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-12-14-004.png" alt="" /></p>

<p>The login name field is a plain text field and the password field is a secure text field. In this case we have two text fields that we need to retrieve in the delegate method:</p>

<pre><code>UITextField *loginField = [alertView textFieldAtIndex:0];
NSLog(@"Login input: %@",loginField.text);

UITextField *passwordField = [alertView textFieldAtIndex:1];
NSLog(@"Password input: %@",passwordField.text);
</code></pre>

<h3>Dynamically enabling/disabling the OK button</h3>

<p>One minor refinement we can make when expecting input from the user is to only enable the OK button when the user has actually entered some text. To perform this validation we need to implement an extra delegate method:</p>

<pre><code>- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
  UITextField *textField = [alertView textFieldAtIndex:0];
  if ([textField.text length] == 0)
  {
    return NO;
  }
  return YES;
}
</code></pre>

<p>The alertViewShouldEnableFirstOtherButton delegate method is called each time the user modifies a text input field in the alert view. It return a BOOL which indicates if the first other button (the OK button in our example) should be enabled or not.</p>

<p>Of course you could do some more sophisticated validation if required but in this case we just check if the user has entered some text into the first text input field. If the text field is empty we return NO which disables the OK button. As soon as the user enters at least one character it is enabled. The Cancel button remains enabled at all times.</p>

<h3>Wrapping Up</h3>

<p>With iOS 5 the UIAlertView class provides a quick and easy way to get a username or password from the user. There is not much code required to implement these additional alert view styles but if you want to play around with the example app I used to generate the screenshots for this post you can find it <a href="http://useyourloaf.com/assets/code/AlertView.zip">here</a> or on my github <a href="https://github.com/kharrison/CodeExamples/tree/master/AlertView">Code Examples</a> page.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Creating Gesture Recognizers with Interface Builder]]></title>
    
      <category term="Gestures"/>
    
      <category term="Interface Builder"/>
    
    <link href="http://useyourloaf.com/blog/2011/11/24/creating-gesture-recognizers-with-interface-builder.html"/>
    <updated>2011-11-24T21:47:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2011/11/24/creating-gesture-recognizers-with-interface-builder</id>
    <content type="html"><![CDATA[<p><em>Whilst I was playing around with Split View Controllers in my <a href="http://useyourloaf.com/blog/2011/11/16/mail-app-style-split-view-controller-with-a-sliding-master-v.html">last post</a> I missed one small trick to eliminate some code. I also overlooked a bug that I need to correct.</em></p>

<p>The example made use of gesture recognizers to allow the master view to be swiped on and off screen. However I created and configured these objects in code rather than with Interface Builder. In this post I will show how easy it is to create gesture recognizers with IB and eliminate some code.</p>

<h3>A quick recap</h3>

<p>Just by way of a recap the example app I used in the last post made use of three gesture recognizers. These were created in the viewDidLoad method of the DetailViewController and added to the detail view. The code that was used to create the three objects is shown below:</p>

<pre><code>    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
                                                                                 initWithTarget:self 
                                                                                 action:@selector(handleSwipeLeft)];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.view addGestureRecognizer:swipeLeft];
    [swipeLeft release];

    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] 
                                                                            initWithTarget:self 
                                                                            action:@selector(handleSwipeRight)];
    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    [self.view addGestureRecognizer:swipeRight];
    [swipeRight release];

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] 
                                                                         initWithTarget:self 
                                                                         action:@selector(handleTap)];
    [self.view addGestureRecognizer:tap];
    [tap release];
</code></pre>

<p>Each gesture recognizer is allocated and initialised with its appropriate target and action, there is some gesture specific configuration such as setting the direction of the swipe or the number of taps we expect and then finally the gesture is added to the view.</p>

<h3>Gesture Recognizers in Interface Builder</h3>

<p>Interface Builder contains a full set of gesture recognizers in its objects library. So instead of creating these objects manually with code we can just drag the required gestures onto our view in the UYLDetailViewController XIB.</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-24a-001.png" alt="" /></p>

<p>Before I do that though I need to correct an error in the example I showed last time. The gesture recognizers were assigned to the top level UIView which includes the toolbar and the toolbar button. This meant that any attempt to tap on the toolbar button was intercepted by the gesture recognizer preventing the button action from being called.</p>

<p>To correct this error I have introduced a subview that covers the entire user interface with the exception of the toolbar. The gesture recognizers can then be assigned to this subview leaving taps on the toolbar button to be handled by the button. For this example we need one Tap Gesture Recognizer object and two Swipe Gesture Recognizer objects. Dragging these objects onto the subview leaves us with a XIB file looks as follows:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-24a-002.png" alt="" /></p>

<p>It is the second view in this list that the gestures are assigned to. If you find your gestures are not working check the Referencing Outlet Collections connection in Interface Builder to ensure they are connected to the correct view:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-24a-003.png" alt="" /></p>

<p>With the gestures added, configuration becomes easier as the inspector shows you the gesture specific configuration options. So the tap gesture allows you set to the number of taps and touches you want to recognize:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-24a-004.png" alt="" /></p>

<p>The swipe gesture allows you set the direction of the swipe (left, right, up, down) and the number of touches:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-24a-005.png" alt="" /></p>

<p>The final step is to set the target-action for each gesture. Using IB you can create the target-action by control-clicking on the object and then dragging into the implementation file. IB will then prompt you for the name of the action to insert:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-24a-006.png" alt="" /></p>

<p>Since in this case we already have the action methods defined we will take a slightly different approach. We will first fix the methods to add IBAction hints for Xcode and then using the same control-click method drag each recognizer object to its method. As you mouse over the action it highlights to show the connection:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-24a-007.png" alt="" /></p>

<p>With the gestures configured and connected there is nothing more to do other than clean up the now redundant code from the view controller. A quick compile and run should confirm that the gestures are recognised and function as before.</p>

<p>The updated Xcode project can be found <a href="http://useyourloaf.com/assets/code/MasterSlide.zip">here</a> or in my <a href="https://github.com/kharrison/CodeExamples/tree/master/MasterSlide">CodeExamples</a> github repository.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mail app style Split View Controller with a sliding master view  ]]></title>
    
      <category term="splitviewcontroller"/>
    
    <link href="http://useyourloaf.com/blog/2011/11/16/mail-app-style-split-view-controller-with-a-sliding-master-v.html"/>
    <updated>2011-11-16T21:51:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2011/11/16/mail-app-style-split-view-controller-with-a-sliding-master-v</id>
    <content type="html"><![CDATA[<p><em>In a <a href="http://useyourloaf.com/blog/2011/10/19/ios-5-split-view-controller-changes.html">recent post</a> I covered a change introduced with iOS 5 that allows the master view of a split view controller to always remain visible in portrait mode. A couple of readers asked if there were any changes to allow the master view to be displayed/hidden with a swipe gesture similar to the way the mail app from Apple now works. My quick answer was that whilst there are no changes in iOS 5 to directly support that style of transition all the functionality to implement it already exists. I thought I would try to expand on that answer with a full example in this post.</em></p>

<h3>Sliding Master View</h3>

<p>To illustrate the idea I will use a very simple master and detail view. The master view is a UITableView with each row named after the row index. The detail view is then simply a label showing the currently selected item. The title of the detail view also shows the selected item. The UI in landscape orientation is shown below:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-14-001.png" alt="" /></p>

<p>In portrait mode there is a button in the toolbar that can be used to show the master view as illustrated below. This looks similar to the standard layout of a split view controller when used with a popover.</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-14-002.png" alt="" /></p>

<p>The difference happens when the master view is displayed either by touching the toolbar button or by using a swipe right gesture. Instead of showing the master view in a popover it slides into view from the left margin covering a portion of the detail view (and the toolbar button). The master view can be dismissed by touching or swiping left in the detailed view.</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-14-003.png" alt="" /></p>

<p>Compare this with the way a master view is displayed with a popover in the standard split view controller:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-18-002.png" alt="" /></p>

<h3>Xcode Master-Detail Template</h3>

<p>I was going to base this example on the Xcode Master-Detail template but to be honest there is not much left from the template so if you want to follow along you may as well just start with an empty application. Whilst on the topic of Xcode templates it is interesting to note that the Master-Detail template does not follow the Apple iOS Human Interface Guidelines. In particular it is recommended not to use navigation controllers for both the master and detail views:</p>

<blockquote><p><strong>Avoid displaying a navigation bar in both panes at the same time</strong>. Doing this would make it very difficult for users to discern the relationship between the two panes.</p></blockquote>

<p>In fact if you create the Split View Controller with Interface Builder it will not even allow you to place a navigation controller as the detail view controller. This is odd as the Apple settings apps actually appears to use a navigation controller for the detail controller, though not for the master view controller. Of course, if you really want to have navigation controllers in both panes you can create the split view controller in code which is what the Master-Detail template does:</p>

<pre><code>UYLMasterViewController *masterViewController = [[[UYLMasterViewController alloc]
  initWithNibName:@"UYLMasterViewController" bundle:nil] autorelease];
UINavigationController *masterNavigationController = [[[UINavigationController alloc]
  initWithRootViewController:masterViewController] autorelease];

UYLDetailViewController *detailViewController = [[[UYLDetailViewController alloc]
  initWithNibName:@"UYLDetailViewController" bundle:nil] autorelease];
UINavigationController *detailNavigationController = [[[UINavigationController alloc]
  initWithRootViewController:detailViewController] autorelease];

self.splitViewController = [[[UISplitViewController alloc] init] autorelease];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavigationController,
                           detailNavigationController, nil];
self.window.rootViewController = self.splitViewController;
</code></pre>

<p>If you are going to use this template you should note that it omits to give the master view controller a reference to the detail view controller (see later) which means you can waste a lot of time wondering why your detail view is not getting updated&#8230;</p>

<h3>Getting Started</h3>

<p>So starting with a fresh Xcode iPad project the first thing I did was create the NIB file for the main window which contains the Split View Controller. The Object layout in Interface Builder is shown below:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-14-005.png" alt="" /></p>

<p>The Window and Split View Connector objects are connected to outlets in the Application Delegate:</p>

<pre><code>@interface UYLAppDelegate : UIResponder &lt;UIApplicationDelegate&gt;

@property (retain, nonatomic) IBOutlet UIWindow *window;
@property (retain, nonatomic) IBOutlet UISplitViewController *splitViewController;

@end
</code></pre>

<p>The Split View Controller always contains two view controllers. The first is the master view controller which will appear in the left-hand pane and the second is the detailed view controller which will appear in the right-hand pane. In this example the master view controller is a navigation controller which contains our class UYLMasterViewController as its root view controller. The detailed view controlled is named UYLDetailViewController.</p>

<p>Normally when implementing the UISplitViewControllerDelegate protocol you would set the delegate of the split view controller to be the detail view controller. If you refer back to the code from the Xcode Master-Detail template you will see that it does exactly that. However the delegate protocol is only needed if you want to implement the popover controller approach or otherwise manage changes to the visibility of the master view controller. In this example we will not be implementing a popover controller so we do not need to set the delegate.</p>

<p>I will not show the NIB files for the master and detail views as they are trivial but for reference here is the interface definition for UYLMasterViewController:</p>

<pre><code>@class UYLDetailViewController;

@interface UYLMasterViewController : UITableViewController

@property (retain, nonatomic) IBOutlet UYLDetailViewController *detailViewController;

@end
</code></pre>

<p>Note that we have defined a property (and IB outlet) for the detailViewController. We will use this later to allow the master view controller to update the detail view controller when the user selects a row. The connection between the master view controller outlet and the detail view controller object is made in the Main Window interface build NIB file.</p>

<p>The definition of the UYLDetailViewController is as follows:</p>

<pre><code>@class UYLMasterViewController;

@interface UYLDetailViewController : UIViewController

@property (retain, nonatomic) NSNumber *detailItem;
@property (retain, nonatomic) IBOutlet UIToolbar *toolbar;
@property (retain, nonatomic) IBOutlet UILabel *detailTitle;
@property (retain, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
@property (assign, nonatomic) BOOL masterIsVisible;

@end
</code></pre>

<p>This is a simple UIViewController containing a UIToolbar which we will use to hold a button and a couple of UILabel objects which will be updated based on the contents of the detailItem object. In this simple example the detailItem object is just an NSNumber which will be set directly from the master view controller. Finally we define a boolean flag which we will use to track when the master view controller view is visible.</p>

<h3>Implementing the Master View Controller</h3>

<p>Actually the master view controller is almost trivial in that it is pretty much a standard UITableViewController. The only difference is that when a row in the table is selected we need to inform the detail view controller so that it can update its view. For the purposes of this example I have hardcoded the table to have a single section containing 20 rows. The content of each row is then simply constructed from the row number:</p>

<pre><code>NSUInteger row = [indexPath row];
cell.textLabel.text = [NSString stringWithFormat:@"Item %u", row+1];
</code></pre>

<p>Since we have a reference to the detail view controller we can directly set the detailItem whenever the user selects a row:</p>

<pre><code>- (void)tableView:(UITableView *)tableView
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  NSUInteger item = [indexPath row] +1;
  NSNumber *detailItem = [NSNumber numberWithInteger:item];

  if (self.detailViewController)
  {
    self.detailViewController.detailItem = detailItem;
  }
}
</code></pre>

<h3>Implementing the Detail View Controller</h3>

<p>Before we look at how to make the master view slide on and off the screen I will cover the basic mechanism used to update the view whenever the master view controller makes a change. This is achieved by providing our own custom setter for the detailItem property which looks as follows:</p>

<pre><code>- (void)setDetailItem:(NSNumber *)newDetailItem
{
  if (_detailItem != newDetailItem) {
    [_detailItem release];
    _detailItem = [newDetailItem retain];
    [self configureView];
  }

  if (self.masterIsVisible) {
    [self hideMasterView];
  }
}
</code></pre>

<p>The storing of a value in the instance variable _detailItem is what you would expect to see in a compiler synthesised setter for a retained property. However in the situation where the value has changed we call the configureView method to update the view. In addition we also hide the master view but I will come back to that later. The configureView method is trivial in this example:</p>

<pre><code>- (void)configureView
{
  if (self.detailItem) {
    self.detailTitle.text = [NSString stringWithFormat:@"Item %@",
                             self.detailItem];
    self.detailDescriptionLabel.text = [NSString stringWithFormat:
                                        @"You selected item %@", 
                                        self.detailItem];
  }
}
</code></pre>

<h3>Adding Gestures</h3>

<p>As described earlier we want to use a swipe right gesture to bring the master view controller into view and either a tap or swipe left to dismiss it. Of course we also only want this behaviour when we are in portrait mode. Gesture recognisers were introduced with the iPad in iOS 3.2 so we will make use of them here. A gesture recogniser is assigned to a view and in this case that means assigning them to the detail view controller view. We can do that easily enough in the viewDidLoad method of UYLDetailViewController:</p>

<pre><code>- (void)viewDidLoad
{
  [super viewDidLoad];

  self.masterIsVisible = NO;

  UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] 
                            initWithTarget:self 
                            action:@selector(handleSwipeLeft)];
  swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
  [self.view addGestureRecognizer:swipeLeft];
  [swipeLeft release];

  UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] 
                            initWithTarget:self 
                            action:@selector(handleSwipeRight)];
  swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
  [self.view addGestureRecognizer:swipeRight];
  [swipeRight release];

  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] 
                                  initWithTarget:self 
                                  action:@selector(handleTap)];
  [self.view addGestureRecognizer:tap];
  [tap release];

  if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
  {
    [self addMasterButton];
  }

  [self configureView];
}
</code></pre>

<p>That looks like a lot of code but it is mostly straightforward:</p>

<ul>
<li>to get started we initialised the boolean flag we are using to track if the master view is visible in portrait mode.</li>
<li>Three separate gesture recognisers are then added to the view. Each gesture recogniser has a separate handler set as the action. The first two gestures are for swiping left and right which is specified by the direction property. The final gesture is for a tap which we will use for dismissing the master view.</li>
<li>If when the view is loaded we are already in portrait mode then we need to add a button to the toolbar to allow the user to view the master view (assuming they do not use the swipe right gesture).</li>
<li>Finally we call the configureView method we saw earlier to setup the view.</li>
</ul>


<p>There are three methods (handleSwipeLeft, handleSwipeRight, handleTap) to handle the various gestures. Since they are very similar I will just show handleSwipeRight:</p>

<pre><code>- (void)handleSwipeRight
{
  if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
  {
    [self showMasterView];
  }
}
</code></pre>

<p>Since we only want our gestures to work when we are in portrait mode we first test the current device orientation. Then if we are in portrait mode we call the showMasterView method to actually bring the master view on screen. The other two methods are almost identical, the only difference is that they call hideMasterView to move the master view off screen.</p>

<h3>Sliding the Master View On and Off Screen</h3>

<p>The one thing that I was not sure about when starting to write this example was exactly how to manipulate the master view. Since the master view is managed internally by the split view controller it is not documented how it shows or hides it when the device changes orientation. A quick look at the view frame in portrait mode tells us the answer. We can move it on and offscreen by adding or subtracting the view width to the x-coordinate of the view frame origin:</p>

<pre><code>(gdb) p rootFrame
$2 = {
origin = {
x = -320,
y = 0
},
size = {
width = 320,
height = 1004
}
}
</code></pre>

<p>At this point I have to add a small word or warning in case you decide to implement this approach in a shipping application. It does not use any undocumented API&#8217;s but it does rely on a specific behaviour of split view controllers that Apple could change in a future release of iOS. So whilst this works now and is very likely to continue to work in future releases there are no guarantees it will not at some point break.</p>

<p>With that warning out of the way we can look at the method to bring the master view controller view onscreen:</p>

<pre><code>- (void)showMasterView
{
  if (!self.masterIsVisible)
  {
    self.masterIsVisible = YES;
    NSArray *controllers = self.splitViewController.viewControllers;
    UIViewController *rootViewController = [controllers objectAtIndex:0];

    UIView *rootView = rootViewController.view;
    CGRect rootFrame = rootView.frame;
    rootFrame.origin.x += rootFrame.size.width;

    [UIView beginAnimations:@"showView" context:NULL];
    rootView.frame = rootFrame;
    [UIView commitAnimations];
  }
}
</code></pre>

<p>Some explanation to walk you through this method:</p>

<ul>
<li>the first thing we do is check our boolean flag &#8220;masterIsVisible&#8221; to see if the master view is already visible. If it is hidden we set the flag to YES and proceed with actually bringing the view onscreen.</li>
<li>To bring the view onscreen we need to retrieve the root view controller that owns the view we want to display. This is easy enough as all view controllers that are contained in a split view controller have a reference to the split view controller. The first object in the viewControllers array is the &#8220;master&#8221; view controller. Note though that this is not our UYLMasterViewController object but the UINavigationController that is inserted at the root of the view controller hierarchy.</li>
<li>Once we have the view from the root view controller we can retrieve its frame and manipulate the x-coordinate of the frame origin to shift it onscreen by adding the width of the view. To make the view slide onto screen we enclose the change to view frame in an animation block.</li>
</ul>


<p>The hideMasterView method is very similar with the exception that we subtract the width of the view from the x-coordinate.</p>

<h3>Adding and Removing the Toolbar Button</h3>

<p>With the view now sliding on and off screen we need to handle the adding (and removal) of a button to the toolbar. You can consider this button optional in that it duplicates the functionality of the swipe right gesture to bring the master view onscreen. However it is not always obvious to users what gestures your app supports so having an additional UI element can sometimes help. One way to think about gestures is to treat them like keyboard shortcuts. Power users will make use of them but not all users may even discover the gesture. If you are going to skip the button consider making the master view have a tab or other visual cue that is visible when the rest of the view is offscreen (the Flixster iPad app is a good example of this approach).</p>

<pre><code>- (void)addMasterButton
{
  UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc]
                                     initWithTitle:@"Master" 
                                     style:UIBarButtonItemStyleBordered
                                     target:self
                                     action:@selector(showMasterView)];
  NSMutableArray *items = [[self.toolbar items] mutableCopy];
  [items insertObject:barButtonItem atIndex:0];
  [self.toolbar setItems:items animated:YES];
  [items release];
  [barButtonItem release];
}
</code></pre>

<p>To add a button to the toolbar we actually need to create a UIBarButtonItem and add that to the UIToolbar items array. The easiest way to do that is to make a copy of the existing items array and insert our new bar button item as the first element of the array. In this case we do not have any other buttons on the toolbar but if we did this approach will preserve those other buttons. Note that the target:action of the button item is set to call the showMasterView method we saw previously. I will skip showing the removeMasterButton method as it simply removes the first item from the toolbar items array.</p>

<p>Now if you refer back to the viewDidLoad method you will see that we already have code to show the button if the device is already in portrait mode when the detail view controller is loaded:</p>

<pre><code>if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
{
  [self addMasterButton];
}
</code></pre>

<p>This is great but what about when the device changes orientation after the view is loaded?</p>

<h3>Handling Orientation Changes</h3>

<p>To handle the situation where the device switches back and forth between portrait and landscape orientations we need to implement the willRotateToInterfaceOrientation:toInterfaceOrientation:duration method:</p>

<pre><code>- (void)willRotateToInterfaceOrientation:
       (UIInterfaceOrientation)toInterfaceOrientation
                                duration:(NSTimeInterval)duration
{
  if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
  {
    [self hideMasterView];
    [self removeMasterButton];
  } else {
    [self addMasterButton];
  }
}
</code></pre>

<p>So if we are moving to landscape orientation we hide the master view and remove the button for the toolbar. Likewise when moving to portrait orientation we simply need to add the button to the toolbar.</p>

<h3>Adding a Border to the Master View</h3>

<p>One final finishing touch is that we need to add a border to the master view to enclose the UITableView. You can spend some time making a nice shadowed box but for now I will just add a border in the App Delegate:</p>

<pre><code>UIView *rootView = [[self.splitViewController.viewControllers
                     objectAtIndex:0] view];
rootView.layer.borderWidth = 1.0f;
rootView.layer.cornerRadius =5.0f;
rootView.layer.shadowOpacity = 0.8f;
rootView.layer.shadowOffset = CGSizeMake(-5, 0);
</code></pre>

<h3>Wrapping Up</h3>

<p>Congratulations if you made it this point - that was a lot of explanation for something which in the end is pretty straightforward. I will leave you with one final comment about this approach. As I mentioned during the post I am relying on a very specific implementation detail of the split view controller which could change in a future iOS release. It is always interesting to play with different implementations but I leave it to you to decide if you are comfortable with this approach for production code. My feeling is that if you want to go beyond Apple&#8217;s implementation of split view controller it might be better to build the complete container class and abandon split view controller completely.</p>

<p>As always you can download the full example app <a href="http://useyourloaf.com/assets/code/MasterSlide.zip">here</a> or in my <a href="https://github.com/kharrison/CodeExamples">CodeExamples</a> github repository.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Stanford iOS development course updated for iOS 5]]></title>
    
      <category term="iOS"/>
    
    <link href="http://useyourloaf.com/blog/2011/11/16/stanford-ios-development-course-updated-for-ios-5.html"/>
    <updated>2011-11-16T21:01:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2011/11/16/stanford-ios-development-course-updated-for-ios-5</id>
    <content type="html"><![CDATA[<p>This quarter&#8217;s lectures from the excellent <a href="http://www.stanford.edu/class/cs193p/cgi-bin/drupal/">Stanford iOS App Development course</a> have just been published to <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=473757255">iTunesU</a>. This years course is again presented by Paul Hegarty and promises to cover iOS 5 specific topics such as iCloud.</p>

<p>At the time of writing only the first 6 lectures are up, so you still have time to catch up if you want to follow along. I recommend this course to anyone looking to get started on iOS development but I think it is also worthwhile for more experienced developers as they often have excellent guest presenters.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Settings Radio Group Element]]></title>
    
      <category term="UIKit"/>
    
    <link href="http://useyourloaf.com/blog/2011/11/01/settings-radio-group-element.html"/>
    <updated>2011-11-01T22:09:00+00:00</updated>
    <id>http://useyourloaf.com/blog/2011/11/01/settings-radio-group-element</id>
    <content type="html"><![CDATA[<p>Whilst playing with the <a href="http://useyourloaf.com/blog/2011/10/24/sync-preference-data-with-icloud.html">iCloud key-value store</a> I came across a new element for the iOS settings application. The Radio Group element was introduced in iOS 5 and is similar in functionality to the Multi Value element. Most of the iOS documentation does not yet mention the Radio Group element with the exception of the Settings Application Schema Reference. Also Xcode 4.2 does not provide direct support when editing the settings property list which makes it a pain to add.</p>

<p>Both elements allow the user to choose one option from a list of possible options but the Radio Group element avoids the need to display the choices on a second page. To illustrate the difference I will add both Multi Value and Radio Group elements to the settings bundle I used to illustrate how to <a href="http://useyourloaf.com/blog/2010/05/18/adding-a-settings-bundle-to-an-iphone-app.html">add a settings bundle to an iPhone app</a>. Refer back to that earlier post for the basics on setting up user preferences.</p>

<h3>Multi Value Element</h3>

<p>The visual appearance of the Multi Value element is shown below for the Retry preference:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-01-001.png" alt="" /></p>

<p>The preference is displayed as a singe line which when tapped takes the user to a second page where the available options can be selected:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-01-002.png" alt="" /></p>

<p>The equivalent entry in the settings property list is as follows:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-01-003.png" alt="" /></p>

<p>The required fields are as follows:</p>

<ul>
<li>Type: PSMultiValueSpecifier</li>
<li>Title: This is the string which is displayed in the settings table.</li>
<li>Key: A string identifier which is used to set and retrieve the preference.</li>
<li>DefaultValue: Default value for the setting.</li>
<li>Values: An array containing the values the user must choose from. You can use any type supported by the preference file. Each value much have a corresponding title in the Titles array.</li>
<li>Titles: An array of strings which is displayed on the second page corresponding to the values defined in the Values array.</li>
</ul>


<p>You can also add a ShortTitles array which provides a shorter string to show in the preference row. Notice in the previous screenshots how the first page show the current value as &#8220;Always&#8221; whereas the corresponding value on the second page has the longer title &#8220;Always Retry&#8221;.</p>

<h3>Radio Group Element</h3>

<p>The Radio Group element removes the need to have a second page and shows all of the options on the initial preferences page as shown below for the Sync preference:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-01-004.png" alt="" /></p>

<p>The entry in the settings property list is as follows:</p>

<p><img src="http://useyourloaf.com/assets/images/2011/2011-11-01-005.png" alt="" /></p>

<p>At the time I am writing this post I am using Xcode 4.2 which does not show the Radio Group as a valid option in an iPhone settings list. This has the side effect that the Item line incorrectly shows the values from the previous item in the settings list. However this does not impact the values written to the settings file (right-click on the file and use Open As > Source Code to see the actual XML).</p>

<p>The fields are similar to the Multi Value element except that the title is now optional since it serves as the title of the table section. Also you can add a FooterText string to include some extra explanatory text below the table group.</p>

<h3>Setting and Accessing Values</h3>

<p>Both preference settings can be accessed in a similar way via the NSUserDefaults class:</p>

<pre><code>NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger syncType = [defaults integerForKey:@"syncType"];
NSInteger retry = [defaults integerForKey:@"retryStrategy"];
</code></pre>

<h3>Wrapping Up</h3>

<p>As long as you do not have a huge list of settings I think the Radio Group element is a nicer choice for selecting from a set of options. It avoids the extra page and the title and footnote help make the settings easier to understand. I guess I should file some bug reports on Xcode and the documentation to ask Apple to update them now that the dust is settling from all the recent launch activity.</p>
]]></content>
  </entry>
  
</feed>

