<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Tewha.net</title>
    <link>https://tewha.net/tags/tricks/</link>
    <description>Recent content on Tewha.net</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 27 Sep 2012 14:00:00 +0000</lastBuildDate>
    <atom:link href="https://tewha.net/tags/tricks/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>How to avoid starting view controllers in the wrong orientation on startup</title>
      <link>https://tewha.net/2012/09/how-to-avoid-starting-view-controllers-in-the-wrong-orientation-on-startup/</link>
      <pubDate>Thu, 27 Sep 2012 14:00:00 +0000</pubDate>
      <guid>https://tewha.net/2012/09/how-to-avoid-starting-view-controllers-in-the-wrong-orientation-on-startup/</guid>
      <description>&lt;p&gt;This is a bit obscure, but I ran into it earlier this week. Why would a view controller appear in the wrong orientation on startup?&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>This is a bit obscure, but I ran into it earlier this week. Why would a view controller appear in the wrong orientation on startup?</p>
<p>When your iPad application first launches it will be in portrait mode, even if it’s held in landscape mode. The rotate event is already in the queue and is consumed early enough that it’ll never actually be shown like that. So no problem, right?</p>
<p>The problem is that the rotate event will not have been consumed when your <code>viewWillAppear:</code> is first called. Opening a new view controller in <code>viewWillAppear:</code> (whether using <code>presentModalViewController:</code> or a storyboard segue) will open that new view controller in portrait mode, rather than landscape mode. Even that wouldn’t be a problem, except iOS will not add a rotate event added for the new view controller.</p>
<p>This all makes a great deal of sense when you think it through: The rotate events for the initial view controller or controllers are already on queue before <code>viewWillAppear</code> is called. iOS already recognizes the device has been rotated; as far as it’s concerned, the rotation is done. Your app is just lagging a bit behind as part of the startup process, with everything all queued up.</p>
<p>Conceptually, this is a hard problem.</p>
<p>But in practice, there’s a very simple and very elegant solution using blocks.</p>
<p>All you need to do is delay your view controller’s appearance. Before blocks, you might have had to use a timer. But now you can just use <code>dispatch_async</code> to schedule the new view controller for later.</p>
<p>That’s a little confusing, so here’s an example:</p>
<p>I have a view controller that appears when my application is first installed, to walk the user through the signup process. (Later, if there’s an authentication problem, I fall back on the standard username and password alert view.)</p>
<p>This view controller, then, needs to appear when my main view first appears. If I use this code, the view controller that appears will always be in portrait, even if the device is started in landscape.</p>
<pre><code>- (void)viewWillAppear: (BOOL)animated {
    [super viewWillAppear:animated];
    if (freshInstall) {
        [self performSegueWithIdentifier: @&quot;firstRun&quot; sender: self];
    }
}
</code></pre>
<p>If I use this code, however, the view controller that appears will match the device (and the view controller it’s appearing over):</p>
<pre><code>- (void)viewWillAppear: (BOOL)animated {
    [super viewWillAppear:animated];
    if (freshInstall) {
        dispatch_async(dispatch_get_main_queue(),^{
            [self performSegueWithIdentifier: @&quot;firstRun&quot; sender: self];
        });
    }
}
</code></pre>
<p>Later in this case is <em>still before</em> the user has a chance to interact, or even before the UI really and truly appears onscreen. The block for showing the view controller will be added to the queue. Everything will just work. By the time your block is run from the main queue, the rotation event will be dealt with and your app will really and truly be in landscape orientation. However, it’ll still be early enough for your view controller to look like part of early application startup.</p>
<p><em>Note: This was done on my “stable” branch, so it was probably on iOS 5. I have not yet tried this on iOS 6, but <a href="https://twitter.com/shusta/statuses/251389962661027842">I’ve read reports this is no longer necessary</a>. Either way, it’s a good trick if you plan on maintaining iOS 5 compatibility (which you should, for a while at least).</em></p>]]></content:encoded>
    </item>
    <item>
      <title>Using blocks to handle errors</title>
      <link>https://tewha.net/2012/06/using-blocks-to-handle-errors/</link>
      <pubDate>Tue, 05 Jun 2012 14:00:00 +0000</pubDate>
      <guid>https://tewha.net/2012/06/using-blocks-to-handle-errors/</guid>
      <description>&lt;p&gt;In the past, I’ve talked about &lt;a href=&#34;https://tewha.net/2011/07/blocks-to-remove-redundancy/&#34;&gt;Using blocks to remove redundancy&lt;/a&gt;. But now I want to explain the pattern I’ve adopted since, which is my favorite block pattern of all. Even though it, too, is all about removing redundancy: handling errors.&lt;/p&gt;
&lt;p&gt;Although Objective-C supports exceptions, they’re not commonly used. A thrown exception is usually not caught, making it a fatal error.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In the past, I’ve talked about <a href="/2011/07/blocks-to-remove-redundancy/">Using blocks to remove redundancy</a>. But now I want to explain the pattern I’ve adopted since, which is my favorite block pattern of all. Even though it, too, is all about removing redundancy: handling errors.</p>
<p>Although Objective-C supports exceptions, they’re not commonly used. A thrown exception is usually not caught, making it a fatal error.</p>
<p><a href="https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocExceptionHandling.html#//apple_ref/doc/uid/TP30001163-CH13-TPXREF168">The Objective-C Programming Language</a> describes it thus:</p>
<blockquote>
<p><strong>Important</strong> In many environments, use of exceptions is fairly commonplace. For example, you might throw an exception to signal that a routine could not execute normally—such as when a file is missing or data could not be parsed correctly. Exceptions are resource-intensive in Objective-C. You should not use exceptions for general flow-control, or simply to signify errors. Instead you should use the return value of a method or function to indicate that an error has occurred, and provide information about the problem in an error object. For more information, see <a href="http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorHandling/ErrorHandling.html#//apple_ref/doc/uid/TP40001806">Error Handling Programming Guide</a>.</p>
</blockquote>
<p>What, then, is the usual pattern for handling non-fatal errors. The answer is the <code>NSError class</code>, along with a few simple conventions:</p>
<ol>
<li>Any method that can fail should return 0 (or an equivalent) on failure.</li>
<li>Any method that fails by returning 0 (or an equivalent) on failure should take a pointer to return a <code>NSError</code> instance, which it populates with error details.</li>
<li>If the error pointer is <code>NULL</code>, the method should not return an error.</li>
</ol>
<p>For instance:</p>
<pre><code>- (BOOL)doSomethingWithError: (NSError **)error {

    // other code
    NSError *e;
    if ( ![self bitWithError: &amp;e] ) {
        if (error) *error = e;
        return NO;
    }
    
    return YES;
}
</code></pre>
<p>This seems pretty reasonable, but can get unmanageable quickly:</p>
<pre><code>- (BOOL)doSomethingWithError: (NSError **)error {
    
    NSError *e;
    
    if ( ![self part1WithError: &amp;e] ) {
        if (error) *error = e;
        return NO;
    }
    
    if ( ![self part2WithError: &amp;e] ) {
        if (error) *error = e;
        return NO;
    }
    
    if ( ![self part3WithError: &amp;e] ) {
        if (error) *error = e;
        return NO;
    }
    
    return YES;
}
</code></pre>
<p>Thankfully, blocks can simplify this for us!</p>
<pre><code>- (BOOL)doSomethingWithError: (NSError **)error {

    BOOL(^fail)(NSError *e) = ^(NSError *e) {
        if (error) *error = e;
        return NO;
    };
    
    NSError *e;
    if ( ![self part1WithError: &amp;e] ) return fail(e);
    
    if ( ![self part2WithError: &amp;e] ) return fail(e);
    
    if ( ![self part3WithError: &amp;e] ) return fail(e);
    
    return YES;
}
</code></pre>
<p>Using a fail block has a few advantages:</p>
<ul>
<li>You have a single place through which all errors in this method are routed. You can put a breakpoint here, or add logging.</li>
<li>If you change what doSomethingWithError returns, you change just the return type of the block and the return within the block.</li>
<li>You eliminate a lot of redundant code, therefore lessening the chance of an error in one of the copies.</li>
</ul>
<p>Footnote: Usually, if I am writing an if statement, I’ll write it like this:</p>
<pre><code>if (foo) {
    // statement
}
</code></pre>
<p>I do this even when it’s not necessary, because what if I expand on it later? And I think this is a good principle. But for a fail block like this, I’m <em>never</em> going to add an extra statement. The whole point of the block is to make sure that the failure code is a single statement.</p>]]></content:encoded>
    </item>
    <item>
      <title>Use a Build Phase to validate XML</title>
      <link>https://tewha.net/2012/04/use-a-build-phase-to-validate-xml/</link>
      <pubDate>Tue, 17 Apr 2012 14:00:00 +0000</pubDate>
      <guid>https://tewha.net/2012/04/use-a-build-phase-to-validate-xml/</guid>
      <description>&lt;p&gt;My application includes some XML files that are used while running to map data from a web service. This has drastically simplified the code I needed to write to parse data from the web service, since I can describe how to decode all of the types of object the web service interacts with simply.&lt;/p&gt;
&lt;p&gt;If I accidentally provide bad XML, I don’t know until my app tries to parse it. That may be some time into its run. If the XML is processed because of a specific user action, I’ve broken that specific user action. So we’re going to build a build phase to validate the XML.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>My application includes some XML files that are used while running to map data from a web service. This has drastically simplified the code I needed to write to parse data from the web service, since I can describe how to decode all of the types of object the web service interacts with simply.</p>
<p>If I accidentally provide bad XML, I don’t know until my app tries to parse it. That may be some time into its run. If the XML is processed because of a specific user action, I’ve broken that specific user action. So we’re going to build a build phase to validate the XML.</p>
<p>Obviously, I want to test everything in my app before I post it to the iTunes Store. But finding this problem even <em>hours</em> later makes it harder to diagnose and fix. I can detect this error immediately (and fix it right away) by adding a build phase to validate my XML.</p>
<p>I added a run script to my target that does this:</p>
<pre><code>find &quot;${PROJECT_DIR}&quot; -name *.xml -exec xmllint {} ;
</code></pre>
<p><em>See update below.</em></p>
<p><img src="/images/Validation-Phase.png" alt="Validation Build Phase"></p>
<p>Xcode will run this script when building my target. It will find all XML files in my project directory, and run <code>xmllint</code> on them. <code>xmllint</code> returns an error if the document is malformed.</p>
<p>I gave this build phase a good name so I can find it easily later, then dragged the script as high in my build phase order as possible to get the results early. This may not actually prevent the project from building, but at least I get a big red error.</p>
<p>This validates <strong>all</strong> the XML in my project directory. If you have XML you don’t need, you’ll have to do something more complicated:</p>
<ul>
<li>Provide a more specific starting path</li>
<li>Use one of the other variables validate the built .app package instead, or</li>
<li>Hard code each XML file’s path</li>
</ul>
<h2 id="update">Update</h2>
<p>This command works better:</p>
<pre><code>find &quot;${PROJECT_DIR}&quot; -name *.xml -print0 | xargs -n 1 -0 xmllint
</code></pre>
<p>With this command, the error not only stops Xcode, but Xcode highlights the line that xmllint reports as the offender.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
