Ben Scheirman

Menu

NSScreencasts, Coming Soon

Bite-Sized Learning

Video training is becoming a very common way to learn these days. With Tekpub, Peepcode, Pluralsight, Code School, and many others, there are usually great productions to teach you any development topic that you’d want to learn about.

All of these services are great, however I’m becoming a fan of the smaller, more focused screencasts. Railscasts, for instance, has been instrumental to my Rails learning development. Destroy all Software teaches me new things every week.

Smaller videos like this are easier to digest, and are more focused on a single topic. Like the boiled frog you eventually realize how far you’ve come on a topic, simply by watching regular videos.

iOS Development is an ever-changing landscape, with so many topic areas to cover, that a single training class or screencast series just can’t teach you all of it. Instead of trying to cover everything in depth (increasing the length of videos). I find it valuable to have smaller, focused tutorials that teach you one thing, and do it quickly and effectively.

Introducing NSScreencast

NSScreencast will be launching soon and will feature regular bite-sized videos focused on a single topic related to Objective-C and building iOS applications.

NSScreencast will include free videos. Down the road, a nominal paid subsribtion will unlock access to more content.

I still have lots to do before I release the first video, but if you like the idea, please sign up on the site to be notified when it launches. Thanks!

Careful With Block-Based Notification Handlers

In general, I prefer using block-based APIs over those that accept selectors.

The block based APIs are generally easier to read & follow, and don’t clutter up your class with methods that are out of context with the code that might potentially invoke them.

An Example

One good example is view animations. Here we’re fading out a view and removing it from the hierarchy once the view has been completely faded out. It’s concise, easy to read, and you don’t need to go anywhere else in the class to get a complete picture of how this works.

Also, since you can have multiple animations going on, having a block-based completion handler means you don’t have to distinguish between what the animations were in some generic completion method.

1
2
3
4
5
[UIView animateWithDuration:0.5 animations:^{
  someView.alpha = 0;
} completion:^ (BOOL finished) {
  [someView removeFromSuperView];
}];

Contrast this with the non-block version:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (void)fadeOutView {
  [UIView beginAnimations];
  [UIView setAnimationDuration:0.5];
  [UIView setAnimationDelegate:self];
  [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

  someView.alpha = 0;

  [UIView commitAnimations];
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
  [someView removeFromSuperView];
}

Block-Based Notification Handlers

NSNotificationCenter also got some block love when iOS SDK 4.0 came around. The old form looked like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (void)setupNotifications {
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(onWhizBang:)
                                               name:MyWhizBangnotification
                                             object:nil];
}

- (void)onWhizBang:(NSNotification *)notification {
  // reload the table to show the new whiz bangs
  [self.tableView reloadData];
}

- (void)dealloc {
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  [super dealloc];
}

This isn’t a lot of code (and it is easy to remember, unlike the previous UIView animation block code), however the action and the notification handler are separated from each other.

The block-based API looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)setupNotifications {
  [[NSNotificationCenter defaultCenter]
      addObserverForNotificationName:MyWhizBangNotification
                              object:nil
                               queue:[NSOperationQueue mainQueue]
                               block:^(NSNotification *notification) {
                                 //reload the table to show the new whiz bangs
                                 [self.tableView reloadData];
                               }];
}

- (void)dealloc {
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  [super dealloc];
}

Aside from some funky indentation, this is preferable in some cases, especially when the action to be completed is as simple as reloading the table.

But there’s a bug. Can you spot it?

Blocks Are Closures

There’s a subtle bug here that you might not notice at first. I didn’t realize this until it was littered all over my code base.

Blocks are closures, and they will capture any values declared outside the scope of the block (and retained) so that they can be used when the block executes. This includes variables declared in the enclosing method or any ivars that you reference from inside the block.

Here, we used self.tableView. self gets retained by the block, which is also retained by self. We have a retain-cycle which is generally a bad thing. It’s especially bad here, because we don’t clear out the block until dealloc, but dealloc won’t ever be called because the block is retaining the instance!

Weak Pointers Save the Day

If you’ve read up on blocks, you’ve probably seen the __block keyword. This specifier tells blocks not to retain the pointer. So all we need is a new pointer, like so:

1
2
3
__block MyViewController *weakSelf = self;

// use weakSelf in the blocks, instead of self

This sort of code drives me nuts. It won’t be apparent to the next developer why it’s there, and it’s pretty ugly.

Retain Cycles are Elsewhere, Too

You might also run into this if you have a parent-child view controller relationship, or perhaps a an parent->object->delegate chain, where the parent is the delegate. This is why you typically mark your delegate property signatures with assign instead of retain semantics.

Not all retain-cycles are terrible though. If you have a way of breaking the cycle, then you just need to weigh how long these objects will remain active for to decide if you need to fix it.

Hopefully this will save you a few headaches down the line.

Formatting JSON From Terminal

I work with JSON APIs a lot. On a current API I work on, there is an OAuth-esque request signing process that is required to make sure that others cannot forge requests simply by changing parameters arround.

A typical request might look like this:

1
2
3
4
5
6
7
8
9
HTTP 1.1
GET /foo/bars.json

Headers:
    Accept-Encoding = gzip;
    Accept = application/json
    Authorization = "cHOLIOb7bAeqFEmsz3io%2Bxg4sQA%3D";
    Account-Id = 201;
    User-Agent = "...";

The Authorization header is generated by concatenating the HTTP Method, URL, any parameters, and then signed with a key.

Because of this security, it is very difficult to create adhoc requests just to try them out. So instead, we have our iPhone app NSLog the proper curl command for us. Now it’s as simple as copy & paste from the Xcode Console, which gives me a less-than-readable output of the JSON.

Usually for this I just pipe the command into pbcopy to get it on my clipboard, then I visit JSON Lint to make it easy to read.

Doin’ it all from Terminal

I looked at ways of doing this all from the Terminal, and came across this python command:

1
python -mjson.tool

It takes input from stdin and outputs it formatted nicely. Sweet! Now all that’s needed is to make this a bit more easy to remember, so I made a script to do this for me called format_json and put it in my path.

Now, any time I want to see the JSON output of an API, I can simply type:

1
2
$ curl some.server.com/api/devices.json?key=124512312 -H Authorization:"124151231231123123" |
    format_json

And here is the output:

1
2
3
4
5
6
7
8
9
10
11
12
{
  "devices": [
      {
          "device_id": "40f4fc8a5818608dbb9a6c981179222b6f",
          "device_type": "iPhone",
          "id": 24,
          "name": "Ben's iPhone",
          "push_enabled": true,
          "push_token": "a3a36......480c25fdf"
      }
  ]
}

Very handy, indeed.

Houston Tech Fest 2011 Recap

Houston Tech Fest 2011 came and went, and yet again was a great success. I believe it was the biggest one ever, with over 1,300 registrants.

I gave three talks:

You can find the slides & code used in the presentations here on github.

If you attended any of these sessions, I’d really appreciate if you rate them using the links above.

See you next year, Houston Tech Fest!

Appsites Is Now AppKickstand

A few weeks ago I launched Appsites, a free way to quickly host an attractive splash page for iPhone applications.

Instead of competing with another site with the same name for traffic when we could be sharing it, I decided a new name was in order.

I now present to you: AppKickstand.

AppKickstand

For an example of what it looks like with real apps, check out Giggle Touch or Tally Things.

If you have an iPhone app, what are you waiting for? It’s FREE!

Sharing Vim Configuration Between Machines

I do most of my development on my MacBook Pro, however I have a nice 27” iMac at home, and it is refreshing to use it for development when I can. It’s fast and has a huge screen. The only downside is all my custom development configurations are on my MacBook Pro!

There are a number of options you can use to share settings between machines, but I’m a fan of using Dropbox (referral link). Any change I make, on either machine, will get automatically synchronized for me.

Since my Vim configurations were already present on my MacBook Pro, the first step was to copy them over to a Dropbox folder:

1
2
3
4
5
mkdir ~/Dropbox/vim
cp -R ~/.vim ~/Dropbox/vim
cp ~/.vimrc ~/Dropbox/vim
cp ~/.vimrc.local ~/Dropbox/vim
cp ~/.gvimrc ~/Dropbox/vim

The next step was to come up with an installer script that would symlink these files on a new machine. I made sure to move existing vim files to a temporary filename so that I wouldn’t lose anything accidentally.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
set -o errexit

function confirm()
{
    echo -n "$@ "
    read -e answer
    for response in y Y yes YES Yes Sure sure SURE OK ok Ok
    do
        if [ "_$answer" == "_$response" ]
        then
            return 0
        fi
    done

    # Any answer other than the list above is considerred a "no" answer
    return 1
}

function link_file()
{
  echo "symlinking $1"
  ln -s "$PWD/$1" "$HOME/$1"
}

echo "This will remove any existing vim configuration files and simlink them with the files here."
confirm "Are you sure?"
if [ $? -eq 0 ]
then
  for file in ~/.vimrc ~/.vimrc.local ~/.gvimrc
  do
    if [[ -f $file ]]; then
      echo "Moving $file to $file.bak"
      mv $file $file.bak
    fi
  done

  for dir in ~/.vim
  do
    if [[ -d $dir ]]; then
      echo "Moving $dir directory to $dir.bak"
      mv $dir $dir.bak
    fi
  done
fi

echo "symlinking"

for file in .vim .vimrc .vimrc.local .gvimrc
do
  link_file $file
done

echo "Done.  Check that it works.  If so, you can remove the .bak files, if any"

Make sure the script is executable by running:

1
chmod +x setup.sh

Then run this script on any new machine that you want to use Vim on. It will symlink these files from your Dropbox folder to your home folder:

  • .vim/
  • .vimrc
  • .vimrc.local
  • .gvimrc

After it’s done, check that it is working. Remove any .bak files that you don’t need anymore.

And that’s it. You have an automatic Vim configuration synching system between machines. It works great for your shell configuration as well!

Making a UIButton Flip Over

If you’ve used the iPod app on the iPhone, you’ve probably seen an interesting trick when switching from album art to the track listing: the button in the top right corner flips over synchronized with the flip animation of the main view.

I wanted to achieve a similar effect for the iPhone app that I’m building, Deli Radio (app store link).

If you’ve ever struggled with the flip transitions before, you probably know how finicky it can be to get it all working. The best way to set it up is to have a parent view contain both views that you want to swap, and set the animation transition type on that view.

For a button (either in the navigation bar or elsewhere) we’d need to introduce a parent view to achieve this effect. This is how I achieved the effect.

First, I had two images I wanted to use for my UIBarButtonItem.

I wanted this to be easily reusable (since I need to do this in more than one place in this application), so I created a category method on UIButton.

It may look strange that a UIButton class method returns a UIView instance, but we need to have a container view to base the animations off of.

Here is the implementation:

I am using a little-known technique of setting associated objects using objc_setAssociatedObject(...). This uses the runtime to attach state to an existing class without needing to subclass.

Now that you understand how it is all setup, the block body will now make sense:

Usage is really easy. I just created a bar button item with a custom view, and was done.

1
2
3
4
5
6
7
8
9
10
11
12
13
UIImage *firstImage  = [UIImage imageNamed:@"btn-info.png"];
UIImage *secondImage = [UIImage imageNamed:@"btn-images.png"];
UIView *container    = [UIButton flipButtonWithFirstImage:firstImage
                                              secondImage:secondImage
                                          firstTransition:UIViewAnimationTransitionFlipFromRight
                                         secondTransition:UIViewAnimationTransitionFlipFromLeft
                                           animationCurve:UIViewAnimationCurveEaseInOut
                                                 duration:0.8
                                                   target:self
                                                 selector:@selector(flipContent)];

self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
  initWithCustomView:container] autorelease];

The effect can be seen below.

Note that the flip effect on the main view is achieved separately, but the 2 strategies share identical values for the animation, so the flip transition types match, as well as the duration & animation curve.

The code for this can be seen in the ChaiOneUI project on Github.

Creating a Glow Effect for UILabel and UIButton

One recent iPhone design mockup called for a glowing effect for a UIButton.

This can be accomplished with images, however I needed a series of buttons to have the same glow effect, and it can easily be accomplished with Core Graphics.

The first step is to include the Core Graphics headers:

1
#import <QuartzCore/QuartzCore.h>

Next, the effect is achieved by using a shadow with no offset (meaning the shadow will be directly underneath the text, not shifted down or to the right). The layer is then given a shadow radius & opacity to allow the shadow to bleed outward. Unsetting masksToBounds will allow the glow to be drawn even outside of the label’s frame. Finally the shadow color is set to either the foreground color or something a bit lighter.

1
2
3
4
5
6
UIColor *color = button.currentTitleColor;
button.titleLabel.layer.shadowColor = [color CGColor];
button.titleLabel.layer.shadowRadius = 4.0f;
button.titleLabel.layer.shadowOpacity = .9;
button.titleLabel.layer.shadowOffset = CGSizeZero;
button.titleLabel.layer.masksToBounds = NO;

This effect works on plain UILabel or the titleLabel property of a UIButton. You can see the results of the effect here:

Don’t go overboard with this. It’s a subtle effect, but looks great when used effectively.

Introducing App Sites

I’ve not been that great about marketing Giggle Touch. It’s a cool app, kids like it, but most people don’t know about it.

The biggest reason was probably that I never set up a proper website for it. Doing a search would only yield a blog post that said it was “coming soon.”

That’s all changed now. I’d like to introduce App Sites.

App Sites

The premise is simple: standup a website for an iPhone app in minutes.

Check it out here: http://appsites.heroku.com.

You can see the site in action by visiting the Giggle Touch page.

It’s free (for now) and gives you the ability to add features, a description, a link back to the app, and a screenshot.

Planned upcoming features include:

  • Custom domains
  • Multiple screenshots
  • Videos
  • Coming soon (if the app hasn’t launched yet)
  • More analytics

If you have an iPhone app, I encourage you to create a page. Let me know what you think!

Firebug-Style Visual Debugging for iOS

Using a crazy helpful library called DC Introspect you’re able to easily take an app running in the Simulator:

And get visual frame debugging information like this:

You can also click & drag your mouse to get pixel information, surrounding frames, print out detailed frame information in the console, and even move frames around all while the app is running.

Using it is incredibly simple:

  • Make sure you have DEBUG defined in your Preprocessor Macros:

1
    #import "DCIntrospect.h"
1
2
3
4
5
6
7
// in applicationDidFinishLaunching:

[self.window makeKeyAndVisible];

#ifdef TARGET_IPHONE_SIMULATOR
    [[DCIntrospect sharedIntrospector] start];
#endif

Once that is done, the library will be loaded and you can use it. When the simulator launches, just press Spacebar to activate the tool.

Here are some keyboard shortcuts:

  • o – Outline all views
  • ? – Prints out a help view
  • f – Flash on drawRect: calls
  • c – Toggle showing coordinates
  • 4 6 8 2 – Nudge the selected view left, right, up, down
  • 0 – Recenter view where it was originally
  • 9 7 3 1 – Modify Width & Height of selected view

You can also click & drag with the mouse to get detailed information about frames & mouse position.

I am amazed at how awesome this library is. I’ll be using it in my default toolbox from now on.