JSON + iOS 5; GO! (Tutorial)

May 30, 2012

What is JSON? JSON stands for JavaScript Object Notation. It’s a super lightweight and human readable data format. Go check it out and run back here.

iOS 5 includes classes to deal with JSON natively. Which is awesome. Let’s do this!

Twitter has a service that gives you recent tweets in JSON format when you give it a URL. Like this:

https://api.twitter.com/1/statuses/user_timeline.json?screen_name=jmenter&count=10

That’ll give you my 10 most recent tweets in JSON format. Easy peasy. Let’s make an app.

In Xcode, New Project, Single View Application. Use ARC. Coolio.

Add a UITableView to the view. Add it as a property to the ViewController, add the data source and delegate and wire those up.

Add some methods to the ViewController.m: one to issue a request and one to handle it. Fix up the data source and delegate methods.

Done. This was not really a tutorial. Sorry to trick you.

Get the Xcode project here, check out the ViewController.m, and see how easy it is!

Advertisements

Showing and Dismissing a UIPickerView Control

April 28, 2012

There seems to be no standard way of dealing with UIPickerViews. Sometimes they are attached right to the bottom of the interface and never move around (like in the built-in Clock application.) Other times they fly up from the bottom like the keyboard but are embedded in a UIToolbar or UIActionSheet.

I’ve come up with a way of dealing with UIPickerView controls that I kind of like. Here’s the gist:

  1. The UIPickerView hides and shows very similar to how the keyboard hides and shows.
  2. When the UIPickerView shows, the rest of the view (including the navigation bar) is dimmed.
  3. Tap anywhere in the dimmed area to hide the UIPickerView. The dismissal tap just dismisses the UIPickerView and won’t be picked up by the view in the background.

To do this we create a custom UIView whose only job is to dim the background and receive the dismissal tap. Once everything is wired up, we hide and show the picker with – (void)showPickerView and – (void)dismissPickerView. Easy!

Here’s why I like it:

  1. Dimming the background puts the UI focus on picking. You can still see the background and the context in which the pickerView showed up (and it can still change state depending on what has been picked in the view.)
  2. A “done” button, while unambiguous, would cover up precious screen real estate and is a smaller target to hit than a dimmed background.
  3. At least for me, tapping the dimmed background to dismiss feels very natural. The fact that the background is dimmed implies that my taps will not affect any of the controls and whatnot in the background.

I’ve created an Xcode project that has an example. Feel free to take a look and use this in your own projects. The comments should make everything clear. I tried to think of a way to make the whole thing more modular (perhaps implementing this all as a subclass of UIPickerView?) but the complexities of having views in the navigation controller and animating everything confused me. Maybe when I’m smarter…

If you find this useful, let me know.


App-A-Week Challenge Update, also Font Tip! (Also, Snippets!)

April 16, 2012

PizzaPal has been updated to 1.1 with the following changes:

  • Removed iAds.
  • Added 4th pizza comparator.

Yeah, I know, that’s kind of cheap to count that as an app release. Whatever, making an app a week is no picnic.

Oh, also, if you do any kind of coding/programming, you should totally check this out:

I’ve switched my programming font of choice from the venerable Consolas for BBedit (14 pt) to the wonderful Inconsolata (15 pt). Inconsolata is simply a beautiful monospaced font that is easy to read, renders beautifully, and yet has TONS of character. My only criticism so far is that the underscore (_) character renders a bit thin. OH WELL. Seriously, download this font and give it a whirl. You shan’t be disappointed.

Also: holy crap why have I never used snippets in Xcode 4 before? Maybe because it’s not entirely obvious how to use them or maybe I was just not as smart a programmer as before. Anyway.

Here’s how to use snippets:

1) type out the thing you want to make a snippet of. Any “bubble text tab” thingees you can create with <#sometext#>. Drag it to the snippet library.

2) Give it a nice title, completion shortcut, and double-check for perfection:

3) Since snippets are sensitive to scope, you can make one for interface and one for implementation!

4) To use, just tap the completion shortcut letters, for example:

Basically, if you find yourself typing similar things over and over again in Xcode, make a snippet RIGHT NOW!


Do free apps increase sales of paid apps?

March 12, 2012

Some of you might remember my crazy idea of pledging to publish an app a week. I thought that this idea would be a good way to force myself to learn a lot about iOS development and actually get things done. And it has!

But one thing I did not consider was how downloads of simple, silly, free apps would affect sales of my paid apps. It’s only been one week but I am pleased to report that there has been some positive influence!

I had two free apps come out last week: The Beer Nerd’s Old Volume Equivalence Calculator came out on Wednesday and Pizza Pal came out on Friday. What you’re about to see are weekly sales figures for last week that cover free iOS apps, paid iOS apps, and paid Mac OS apps.

First, let’s take a look at the free iOS apps:

 

Even though the new free apps didn’t come out until later in the week, we’re seeing a 4-8x increase in free app sales. It was hovering between 10 and 20 a week and shot up to 80 last week.

So, we have users downloading the free silly apps. How might that affect sales of paid apps?

It appears that sales have roughly doubled from 30/week to 60/week. Nice! Is it possible that this increase works for Mac OS X apps as well?

This is not as clear but there appears to be an increase. It might average out to twice as much but I haven’t done any maths on it yet.

It has only been a week but it seems pretty clear that adding free apps to your stable of apps helps increase sales of your paid apps. And increases your skills and experience! LEVEL UP!


Possible bug in UITableViewCell didTransitionToState:(UITableViewCellStateMask)state

March 9, 2012

I’m putting this out here on the internets because I was pulling my hair out about this problem I had. Let me see if I can explain the problem and how I ended up solving it without turning this into a super long story.

I’m working on a new app that is basically a brewer’s countdown timer. I have a UITableViewController with a UITableView that has some custom UITableViewCells created via subclassing.

In the UITableViewCell subclass I implement:

- (void)didTransitionToState:(UITableViewCellStateMask)state
 So that I can use an animation block to adjust the opacity of cells that transition to state UITableViewCellStateShowingDeleteConfirmationMask. (I also check for UITableViewCellStateDefaultMask so I can turn them back to normal if the user cancels.) The problem happens thusly:
  1. Swipe cell to delete. The cell fades with the animation block and the delete confirmation button shows up as we would expect. GOOD!
  2. (If we tap away to cancel, the cell returns to normal.) GOOD!
  3. If instead, of tapping away, we tap “delete”, the
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
     gets called and we delete the cell from the table and the data source programmatically. It flies away. SO FAR SO GOOD.
  4. The cell directly after the deleted one moves up into the proper place BUT THEN DIMS ACCORDING TO the logic in the
    didTransitionToState:(UITableViewCellStateMask)state

    method. BAD!

The cell directly afterwards should not be getting the didTransitionToState method called on it. This problem persisted if I was using reusable cells or not. Here’s how I solved it:

In

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
 I added:
tableView.editing = NO;
 right before removing the data source and deleting the rows. Apparently the “swipe to delete” automatically puts the tableView into edit mode and doesn’t bother to get it out of edit mode automatically. It feels like what was going on was that the UITableView cell directly after the deleted one was inheriting the deleted one’s UITableViewCellStateMask and since it was in edit mode, the willTransitionToState got called automatically. Setting the editing property of the tableView before deleting seems to reset the state mask.

Here’s a picture and also a tiny preview of what I’m working on!


New app! Also: Xcode + iOS + iPhone 3G tip. Also: insane idea.

March 7, 2012

I have a new app on the iTunes App Store! Allow me to introduce The Beer Nerd’s Olde Volume Equivalence Calculator:

It’s a handy little app that lets you compare equivalent prices for different volumes of beer. Interesting? Maybe. In all honesty, I whipped this app up real quick for the following reasons:

  1. It uses the new accurate UISlider subclass I’ve been working on (which I will open source soon!)
  2. It has an iAd. Ooh or eew? I don’t know yet.
  3. I’m trying something new to help increase my skills. It’s kind of like Jonathan Coulton’s Thing a Week. I intend to write and publish a new app every week for the next year. What?

That last item seems like it might be a doozy. Not every app is going to be a winner. Apple may kick me out for generating too much crapware. Most will be free or iAd supported. Some might be decent.

There is a lot of doubt entwined with this idea. But here is something about which I don’t have much doubt: writing and releasing an app a week will stretch all parts of my development skillset, from writing code to understanding design patterns to designing icons to submitting and packaging. We’ll see how this goes. App #1 is done, app #2 is waiting to be reviewed and app #3 is nearing completion. Also, I haven’t forgotten about Lens•Lab! I’ll count an update of that as part of an app a week.

Oh, and the Xcode + iOS + iPhone 3G tip is this: when you create a new project in Xcode 4.2, the plist for your app has a entry called “armv7” in the “Required device capabilities” section.

If your app targets iOS 4.2.1 and lower, you MUST remove this entry to support armv6 (the processor variant in the original iPhone, iPhone 3G, and 1st and 2nd generations of iPod Touch.) I just found this out this morning and an update to The Beer Nerd’s Olde Volume Equivalence Calculator has been submitted to Apple!


How I Falsified My Most Cherished User Interface Hypothesis

February 4, 2012

I’ve been working on subclassing and improving the venerable UISlider class in iOS’s UIKit framework.

Here’s what I was thinking: UISlider is a great way for the user to enter numerical values within a certain range very quickly. It’s immediately responsive and by default gives continual updates as to its value. The problem is that it’s not really all that accurate. There are two ways in which the slider manifests inaccuracies:

  1. Though the value reported by the control is a float, there are only so many physical pixel positions upon which the thumb can lie along the track. In the example above, the slider is 284 points wide. Subtract 11.5 points from either side (these are the areas where the thumb can’t go) and you have 261 discrete positions along the track where the thumb can physically sit and indicate value. If the minimum and maximum values are, say, 100 and 1000 then we’re talking 3.4 value units for each point of physical space on the track.
  2. Even if you can get really accurate with your finger, chances are the value is going to change slightly when you lift up your finger. This is a byproduct of how positions are reported by the hardware.

There are only two values that are selectable with very gross accuracy: the minimum and the maximum.

It seemed like Apple even acknowledged this deficiency starting with iOS 4. If you use the scrubber in the Music (or iPod) app, you can change scrubbing accuracy of the slider by moving your finger perpendicular away from the track. As you move, you get textual feedback (two lines of text; one above the track and one below) telling you about how the slider is behaving.

I thought this was a really interesting solution to the problem of slider accuracy, but I thought that there were two things about Apple’s implementation that were not quite right:

  1. There is no visibly obvious way for the user to know that the slider works in a unique way.
  2. The only hint that it does work in a unique way are the two lines of text, the one on top indicates the current scrubbing speed, the one on the bottom describes how to use the control.

It seems to me that if you have to use two lines of text to describe how a control works, you have failed. So, here is my attempt at improving the control:

I thought Ole Begemann’s open source implementation of this in UISlider was really cool but I wanted to improve it even further. I wanted continuously increasing accuracy (instead of steps like in Ole’s version) and I wanted visual feedback indicating what was going on with the control (Ole’s version has no special appearance to it.)

What I have created is a subclass of UISlider that improves its functionality. Here’s how:

  1. By itself (when you’re not interacting with it) the slider looks totally normal.
  2. As soon as you touch the thumb, two indicators appear (actually, they fade in over 0.2 seconds.) They resemble the jaws of a caliper.
  3. The job of these two indicators is to display to the user how accurate the slider is behaving. As your finger moves up (or down) away from the track, the jaws move inward to indicate that the “area of concern” on the track is shrinking. The thumb moves markedly slower than the users finger. The areas of track outside the “area of concern” are dimmed to indicate that they are not selectable at the current level of accuracy. As the user’s finger gets further and further from the track, the jaws move even further inward and the accuracy of the thumb (including the value extracted programmatically) increases dramatically.
  4. When the user releases their finger, the jaws and disabled areas of track move back to their original positions and fade out.
  5. There is a vertical 20pt or so “dead zone” along the track where accuracy is totally normal (i.e.; not fine.) This allows the control to work “mostly as normal” yet the appearance of the caliper jaws gives the user the idea that something more might be going on.

As I was building this, I was thinking (hypothesizing) that if I got this right, that would make the slider a really good way of entering numerical data. It seemed like one could easily get accurate numeric data entered quickly.

So, I built it (well, there’s still a bit of work to do but it’s close enough to “done” to test) and decided to actually test to see how well it worked.

I built an iPhone project in Xcode that had 4 tab views. Each tab view had a unique method of entering numeric information and I programmed each one to record how long it took for the user to enter the specific numeric value we wanted. The 4 methods were:

  1. UISlider (min:1, max: 100)
  2. UIAccurateSlider (my special subclass, same values as above)
  3. UIPickerView (4 wheels: two single digit wheels, a period, and a final digit wheel)
  4. UITextField (with numeric keyboard popup.)

I tested on myself and was stunned at what I saw. After trying it a bunch of times, here are some rough ideas about how long it took for me to enter the value of 84.3:

  1. UISlider: gave up
  2. UIAccurateSlider: 13 seconds
  3. UIPickerView: 6 seconds
  4. UITextField: 3 seconds

Now, this is kind of a “best case scenario” with a user who is not only good with computer, but also wrote how one of them behaves.

I guess I was hoping that my fancy, more accurate UISlider would be so awesome that it could almost replace any kind of text input area (at least where values sit within certain reasonable ranges.) I was totally stunned at how long it took to enter accurate values with my special slider subclass.

Now, to be fair, the accurate slider I made has benefits that the UIPickerView wheels and the UITextField keyboard doesn’t, most notably, interactivity. It’s possible to enter values and have your UI update in realtime. This is something that’s not possible with the other value input methods.

Anyway. Maybe the UISlider I made can be improved? In the spirit of fairness, openness, and transparency I present the Xcode project I used to do these tests. It needs iOS5. The UIAccurateSlider subclass is in there. It’s totally not production ready so don’t laugh at it too hard. I’ll have a more polished version out very soon.

Thoughts? Leave ’em in the comments.