<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.11.81 (http://www.squarespace.com/) on Fri, 01 Jun 2012 09:01:33 GMT--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>touchalicious.com</title><link>http://touchalicious.com/blog/</link><description></description><lastBuildDate>Sat, 25 Feb 2012 23:02:19 +0000</lastBuildDate><copyright></copyright><language>en-US</language><generator>Squarespace Site Server v5.11.81 (http://www.squarespace.com/)</generator><item><title>UIAlertView is dangerous</title><category>objective-c</category><category>programming</category><dc:creator>Hans Sjunnesson</dc:creator><pubDate>Sat, 25 Feb 2012 22:05:18 +0000</pubDate><link>http://touchalicious.com/blog/2012/2/25/uialertview-is-dangerous.html</link><guid isPermaLink="false">331232:3485744:15186594</guid><description><![CDATA[<p>And so is UIActionSheet. Here's why. Starting with iOS 4, more and more of the standard library replaced its old delegate patterns with block-based handlers.
Here's an example of animating UIViews pre iOS 4:</p>

<pre><code>- (IBAction)buttonTapped:(id)sender {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(viewDidMove:finished:context:)];

    view.center = CGPointMake(50, 50);

    [UIView commitAnimations];
}

...

- (void)viewDidMode:(NSString *)animationId finished:(BOOL)finished context:(void *)context {
    [self updateState];
}
</code></pre>

<p>And for iOS 4+ you'd just do this:</p>

<pre><code>- (IBAction)buttonTapped:(id)sender {
    [UIView animateWithDuration:1.0 animations:^{
        view.center = CGPointMake(50, 50);
    } completion:^(BOOL finished) {
        [self updateState];
    }];
}
</code></pre>

<p>Block-based handlers made it so that you'd write less code. And the code you wrote for your handler was you attached to the code that triggered the animation. Not scattered throughout your code's delegate methods.</p>

<p>However, UIActionSheet and UIAlertView have not been update to use blocks instead of delegates. I think it has to do with their delegate protocols having so many methods. Still, for the most part I only use <code>- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated</code>.</p>

<p>There are a few dangers of using delegates of UIAlertView and UIActionSheets. Aside from forcing you to spread out the code that's relevant to the alert view, I came across a weird bug in one of my apps. I had a UITableViewController with a list of items, which implemented UIAlertViewDelegate. I would pop a UIAlertView asking the user "Do you really want to remove the item named <item>? Yes/No".
Here's the implementation:</p>

<pre><code>- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 0) {
        [self deleteItemAtIndex:self.selectedIndex];
    }
}
</code></pre>

<p>Way later I made a subclass of the UITableViewController, and wrote some code which popped an UIAlertView on network errors:</p>

<pre><code>UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Couldn't connect to the server." message:@"Try again in later." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
</code></pre>

<p>Did you spot where I went wrong? I just filled out the initializer without really thinking about it. This was a fire-and-forget UIAlertView, but I accidentally put <code>delegate:self</code> in there. The subclass didn't implement UIAlertViewDelegate, but its super class did. So whenever I hit "OK", super's <code>didDismissWithButtonIndex</code> would be called with buttonIndex 0.</p>

<p>So you need to always, always, always save your UIAlertView and compare it in your delegate method:</p>

<pre><code>self.theAlertView = [[[UIAlertView alloc] initWithTitle:@"Warning" message:@"Do you really want to remove the item?" delegate:self cancelButtonTitle:@"Yes" otherButtonTitles:@"No", nil] autorelease];
[self.theAlertView show];

...

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    if (self.theAlertView == alertView) {
        if (buttonIndex == 0) {
            [self deleteItemAtIndex:self.selectedIndex];
        }
    }
}
</code></pre>

<p>But what if potentially pop multiple UIAlertViews in a single stack, like with a validation method:</p>

<pre><code>- (void)validateInputs {
    if ([self missingTitle]) {
        self.theAlertView = [[[UIAlertView alloc] initWithTitle:@"Empty title" message:@"Continue?" delegate:self cancelButtonTitle:@"Yes" otherButtonTitles:@"No", nil] autorelease];
        [self.theAlertView show];
    }

    if ([self missingBody]) {
        self.theAlertView = [[[UIAlertView alloc] initWithTitle:@"Empty body" message:@"Continue?" delegate:self cancelButtonTitle:@"Yes" otherButtonTitles:@"No", nil] autorelease];
        [self.theAlertView show];
    }

    if ([self missingImage]) {
        self.theAlertView = [[[UIAlertView alloc] initWithTitle:@"Missing image" message:@"Continue?" delegate:self cancelButtonTitle:@"Yes" otherButtonTitles:@"No", nil] autorelease];
        [self.theAlertView show];
    }
}
</code></pre>

<p>Oops, we've overwritten the <code>theAlertView</code> member, so now we'll have to do something like this:</p>

<pre><code>@property (readonly) NSMutableSet *alertViews;

...

- (void)validateInputs {
    @synchronized (self.alertViews) {

        if ([self missingTitle]) {
            UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Empty title" message:@"Continue?" delegate:self cancelButtonTitle:@"Yes" otherButtonTitles:@"No", nil] autorelease];
            [self.alertViews addObject:alertView];
            [alertView show];
        }

        if ([self missingBody]) {
            UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Empty body" message:@"Continue?" delegate:self cancelButtonTitle:@"Yes" otherButtonTitles:@"No", nil] autorelease];
            [self.alertViews addObject:alertView];
            [alertView show];
        }

        if ([self missingImage]) {
            UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Missing image" message:@"Continue?" delegate:self cancelButtonTitle:@"Yes" otherButtonTitles:@"No", nil] autorelease];
            [self.alertViews addObject:alertView];
            [alertView show];
        }
    }
}

...

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    @synchronzed (self.alertViews) {
        if ([self.alertViews containsObject:alertView]) {
            if (buttonIndex == 0) {
                [self continueAddingItem];
            }

            [self.alertViews removeObject:alertView];
        }
    }
}
</code></pre>

<p>Do you see what a total pain in the ass this is? And the potential for bugs to creep in? And it's the same basic premise with UIActionSheets.</p>

<p>Here's what I'm proposing. Instead of delegates for alert views and action sheets I've implemented subclasses of both these classes, which use blocks as handlers. Now these blocks only cover one of the delegate methods: <code>didDismissWithButtonIndex</code>. If you need any of the other methods, then use the regular classes. For the majority of cases, you're good with didDismiss.</p>

<p>They're up on <a href="https://gist.github.com/1911385">github</a>, go ahead and do whatever. They're under the MIT License.</p>

<p>You use them like this:</p>

<pre><code>[[[HSAlertView alloc] initWithTitle:@"Stuff" message:@"Do stuff?" dismissBlock:^(NSInteger buttonIndex) {
    // Do stuff
} cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", @"Yes", @"No", nil] show];

[[[HSActionSheet alloc] initWithTitle:@"Do stuff?" dismissBlock:^(NSInteger buttonIndex) {
    // Do stuff
} cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"No" otherButtonTitles:@"Yes", @"Maybe", nil] showInView:self.view];
</code></pre>
]]></description><wfw:commentRss>http://touchalicious.com/blog/rss-comments-entry-15186594.xml</wfw:commentRss></item><item><title>2011 is the year I put out</title><dc:creator>Hans Sjunnesson</dc:creator><pubDate>Wed, 06 Apr 2011 20:51:43 +0000</pubDate><link>http://touchalicious.com/blog/2011/4/6/2011-is-the-year-i-put-out.html</link><guid isPermaLink="false">331232:3485744:11073625</guid><description><![CDATA[<p>I've got a ton of ideas for games and fun digital toys and 2011 is going to be the year for putting them out there.</p>
<p>Here's a start. I'm working on a puzzle game. It's not terribly original. Nothing is. But I think it'll be a fun game.</p>
<p>I've sketched out the concept into a rough design doc. And I'm putting it out under the Creative Commons Attribution license. That means anyone can take the idea and basically do whatever fun stuff they want with it.</p>
<p>You can download the design <a href="http://dl.dropbox.com/u/1839929/Prime.pdf">here</a>. It's a pdf, roughly 4 mgb. Excuse my poor handwriting.</p>
<p>&nbsp;</p>
<p>The idea here is to make myself beholden to the good people of The Internet to follow through with this project. But also to challenge the aforementioned good people to see who can make the best version of this game.</p>
<p>I will be posting semi-regularly with my progress.</p>
<p>&nbsp;</p>]]></description><wfw:commentRss>http://touchalicious.com/blog/rss-comments-entry-11073625.xml</wfw:commentRss></item><item><title>Asynchronous unit testing with OCMock</title><category>objective-c</category><category>programming</category><dc:creator>Hans Sjunnesson</dc:creator><pubDate>Thu, 05 Nov 2009 21:29:38 +0000</pubDate><link>http://touchalicious.com/blog/2009/11/5/asynchronous-unit-testing-with-ocmock.html</link><guid isPermaLink="false">331232:3485744:5712067</guid><description><![CDATA[<p>I've recently been using <a href="http://www.mulle-kybernetik.com/software/OCMock/">OCMock</a> more and more.
It's a great <a href="http://mockobjects.com">mocking framework</a> for writing
unit test for the mac or the iPhone.</p>

<p>When I mock delegate objects which wait for asynchronous callbacks I
use this handy utility method</p>

<h2>Update</h2>

<p>There was a bug in here which made the utility return early, no matter how long the delay was.
I've updated the code to fix the bug.</p>

<pre><code>//
//  TestUtils.h
//
//  Created by Hans Sjunnesson on 2009-11-05.
//

#import &lt;Foundation/Foundation.h&gt;
#import &lt;OCMock/OCMock.h&gt;

@interface TestUtils : NSObject {

}

/*!
 @method waitForVerifiedMock:delay:
 @abstract Runs the current run loop for as long as specified by the delay, or until the mockobject verifies.
 @param mock the OCMockObject to verify.
 @param delay the time to wait until the mock is verified, in seconds.
*/
+ (void)waitForVerifiedMock:(OCMockObject *)mock delay:(NSTimeInterval)delay;

@end
</code></pre>

<p>And the implementation:</p>

<pre><code>//
//  TestUtils.m
//
//  Created by Hans Sjunnesson on 2009-11-05.
//

#import "TestUtils.h"


@implementation TestUtils

+ (void)waitForVerifiedMock:(OCMockObject *)inMock delay:(NSTimeInterval)inDelay
{
  NSTimeInterval i = 0;
  while (i &lt; inDelay)
  {
    @try
    {
      [inMock verify];
      break;
    }
    @catch (NSException *e) {}
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
    i+=0.5;
  }
}

@end
</code></pre>

<p>Here's an example of testing 'NSURLConnection' trying to connect to google.com.</p>

<pre><code>@implementation NSObject (NSURLConnectionDelegate)
  - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {}
@end

- (void)testShouldConnect {
  id mock = [OCMockObject mockForClass:[NSObject class]];

  NSURL *url = [NSURL URLWithString:@"http://www.google.com"];
  NSURLRequest *request = [NSURLRequest requestWithURL:url];
  NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:mock startImmediately:NO];
  [[mock expect] connection:connection didReceiveResponse:OCMOCK_ANY];

  [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  [connection start];

  // Wait for five seconds
  [TestUtils waitForVerifiedMock:mock delay:5.0];

  STAssertNoThrow([mock verify], @"Should be able to connect to google.");
}
</code></pre>
]]></description><wfw:commentRss>http://touchalicious.com/blog/rss-comments-entry-5712067.xml</wfw:commentRss></item><item><title>Turn Core Data models into JSON</title><category>programming</category><category>tutorial</category><dc:creator>Hans Sjunnesson</dc:creator><pubDate>Sun, 25 Oct 2009 08:19:39 +0000</pubDate><link>http://touchalicious.com/blog/2009/10/25/turn-core-data-models-into-json.html</link><guid isPermaLink="false">331232:3485744:5599792</guid><description><![CDATA[<p><a href="http://json.org/">Json</a> is a lightweight data-interchange format, says the official website.
Think XML but with a format that's easier for both people and javascript interpreters to parse.
Here's an easy way to serialize Core Data models into json.</p>

<p>First, download <a href="http://github.com/blakeseely/bsjsonadditions/">blakeseely's bsjonadditions</a> project and include the source in your xcode project.
Secondly, copy &amp; paste the following snippet into a new file in your project called <strong>NSManagedObjectExtras.m</strong>:</p>

<pre><code>//
//  NSManagedObjectExtras.m
//

#import "NSDictionary+BSJSONAdditions.h"
#import "NSArray+BSJSONAdditions.h"


@implementation NSManagedObject (NSObject)

- (NSDictionary *)propertiesDictionary
{
  NSMutableDictionary *properties = [[[NSMutableDictionary alloc] init] autorelease];

  for (id property in [[self entity] properties])
  {
    if ([property isKindOfClass:[NSAttributeDescription class]])
    {
      NSAttributeDescription *attributeDescription = (NSAttributeDescription *)property;
      NSString *name = [attributeDescription name];
      [properties setValue:[self valueForKey:name] forKey:name];
    }

    if ([property isKindOfClass:[NSRelationshipDescription class]])
    {
      NSRelationshipDescription *relationshipDescription = (NSRelationshipDescription *)property;
      NSString *name = [relationshipDescription name];

      if ([relationshipDescription isToMany])
      {
        NSMutableArray *arr = [properties valueForKey:name];
        if (!arr)
        {
          arr = [[[NSMutableArray alloc] init] autorelease];
          [properties setValue:arr forKey:name];
        }

        for (NSManagedObject *o in [self mutableSetValueForKey:name])
          [arr addObject:[o propertiesDictionary]];
      }
      else
      {
        NSManagedObject *o = [self valueForKey:name];
        [properties setValue:[o propertiesDictionary] forKey:name];
      }
    }
  }

  return properties;
}  

- (NSString *)jsonStringValue
{
  return [[self propertiesDictionary] jsonStringValue];
}

@end
</code></pre>

<p>Now all you need to do is to call <code>[coreDataModel jsonStringValue]</code> to get the model as a json string.</p>
]]></description><wfw:commentRss>http://touchalicious.com/blog/rss-comments-entry-5599792.xml</wfw:commentRss></item><item><title>Anthony Burch rants on indie games</title><category>indie-games</category><dc:creator>Hans Sjunnesson</dc:creator><pubDate>Tue, 04 Aug 2009 20:05:00 +0000</pubDate><link>http://touchalicious.com/blog/2009/8/4/anthony-burch-rants-on-indie-games.html</link><guid isPermaLink="false">331232:3485744:4821387</guid><description><![CDATA[<p><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/joOZ8DlT2sU&amp;hl=sv&amp;fs=1&amp;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/joOZ8DlT2sU&amp;hl=sv&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p>

<p>I'm dizzy from nodding in agreement with this video rant from <a href="http://www.destructoid.com/elephant/index.phtml?a=1334">Anthony Burch</a>.
He touches on the state of big-media games, with massive budgets and marketing vs. independently created, small games.</p>

<p>One of the point he makes is how consumers willingly fork over sixty bucks for a pile of crap, while independent game makers put out wonderfully moving pieces such as <a href="http://www.ludomancy.com/games/today.php?lang=en">"Today I Die"</a> and <a href="http://hcsoftware.sourceforge.net/passage/">"Passage"</a> and are having a hard time scraping by on donations.</p>

<p>Watch the video, take some time to play the games that Burch talks about and if you enjoy them, donate a few bucks for the good cause.</p>
]]></description><wfw:commentRss>http://touchalicious.com/blog/rss-comments-entry-4821387.xml</wfw:commentRss></item><item><title>A simple multipart/x-mixed-replace HTTP test-server</title><category>programming</category><category>ruby</category><dc:creator>Hans Sjunnesson</dc:creator><pubDate>Sat, 25 Apr 2009 21:45:07 +0000</pubDate><link>http://touchalicious.com/blog/2009/4/25/a-simple-multipartx-mixed-replace-http-test-server.html</link><guid isPermaLink="false">331232:3485744:3799799</guid><description><![CDATA[<p>I've recently fiddled around with streaming HTTP connections.
I needed to make a client which interfaces with an HTTP server that streams data via <em>Content-type: multipart/x-mixed-replace</em>.</p>

<p>Unfortunately NSURLConnection turned out to handle multipart/x-mixed-replace really poorly.
More on that later though. For now I just wanted to share a simple ruby script I created to test my client.</p>

<p>The script serves multipart/x-mixed-replace over HTTP. You can get it over at <a href="http://github.com/hsjunnesson/Multipart-Streaming-HTTP-Server">github</a>.</p>

<p>The entire script after the jump.</p>
]]></description><wfw:commentRss>http://touchalicious.com/blog/rss-comments-entry-3799799.xml</wfw:commentRss></item><item><title>I've updated frame animator</title><category>programming</category><category>sprite animation</category><category>tutorial</category><dc:creator>Hans Sjunnesson</dc:creator><pubDate>Thu, 02 Apr 2009 20:01:05 +0000</pubDate><link>http://touchalicious.com/blog/2009/4/2/ive-updated-frame-animator.html</link><guid isPermaLink="false">331232:3485744:3540649</guid><description><![CDATA[<p>This is a followup to my <a href="http://touchalicious.com/blog/2009/3/29/a-frame-by-frame-sprite-animator-for-core-animation.html">previous article</a> on my frame sprite animator for Core Animation. Read that article first, ff you haven't alreday.</p>

<p>I've updated my frame sprite animator.
It's a little faster now, but more importantly, I've added a callback mechanism.</p>

<h2>Callbacks</h2>

<p>By default, a sprite is registered for <em>HSAnimationModeLoop</em> mode.
But you can register an object to receive a callback from the animator when a sprite which has finished animating for the new animation mode <em>HSAnimationModeOnce</em>.</p>

<p>So for example, this is how to register a sprite to animate for the "KICK" frameset, set to animate only once, and then receive a callback.</p>

<pre><code>[animator_ setCallback:self];
[animator_ registerSprite:sprite forFrameset:@"KICK" andAnimationMode:HSAnimationModeOnce];
</code></pre>

<p>And then implement the callback method.</p>

<pre><code>- (void) hasFinishedAnimatingSprite:(CALayer*)sprite forFrameset:(NSString*)frameset {
  // Just re-register the sprite for the STAND frameset.
  [animator_ registerSprite:sprite forFrameset:@"STAND"];
}
</code></pre>

<p>It's as simple as that.</p>

<h2>Source</h2>

<p>I've updated the source over at <a href="http://github.com/hsjunnesson/spriteanimationframework">GitHub</a>. I've also updated the simple demo-application.</p>
]]></description><wfw:commentRss>http://touchalicious.com/blog/rss-comments-entry-3540649.xml</wfw:commentRss></item><item><title>A frame-by-frame sprite animator for Core Animation</title><category>programming</category><category>sprite animation</category><category>tutorial</category><dc:creator>Hans Sjunnesson</dc:creator><pubDate>Sun, 29 Mar 2009 09:37:17 +0000</pubDate><link>http://touchalicious.com/blog/2009/3/29/a-frame-by-frame-sprite-animator-for-core-animation.html</link><guid isPermaLink="false">331232:3485744:3498727</guid><description><![CDATA[<p>Core Animation makes animations as easy as setting a property.
Animating properties such as position and rotation has been made trivial by Core Animation, but I often see people asking how to do a frame-by-frame animated sprite using Core Animation CALayers.
This isn't something that comes out "of the box" with Core Animation.
But it is fairly easy to write a good-enough animating class which uses a timer to, at a reoccurring interval, set the contents property of a CALayer.</p>

<p>Read on for the full article.</p>
]]></description><wfw:commentRss>http://touchalicious.com/blog/rss-comments-entry-3498727.xml</wfw:commentRss></item><item><title>Context Free Art!</title><category>context free art</category><category>programming</category><dc:creator>Hans Sjunnesson</dc:creator><pubDate>Sun, 22 Mar 2009 18:34:47 +0000</pubDate><link>http://touchalicious.com/blog/2009/3/22/context-free-art.html</link><guid isPermaLink="false">331232:3485744:3404454</guid><description><![CDATA[<p>I've recently discovered the wonderful world of <a href="http://www.contextfreeart.org/">Context Free Art</a>. It's a way of procedurally generating images through a simple programming language.</p>

<p>The thing that drives me about context free art is how it enables me to create incredibly complex images from a few lines of simple code. And it's got a great community where you post your designs for everyone to comment on.
Often other programmer artists will give you helpful tips or code variants which make your designs come out in radically different ways.</p>

<p>Continue reading to see some of the designs I've created.</p>
]]></description><wfw:commentRss>http://touchalicious.com/blog/rss-comments-entry-3404454.xml</wfw:commentRss></item></channel></rss>
