Tuesday, March 8, 2011

Cocoaheads Talk - Introduction to Unit Testing

Yesterday I did a short presentation at Cocoaheads Stockholm. I talked about unit testing and showed an example of how to divide your code to make it more testable. The example project together with the slides from the presentation are available on github.

While on the topic of testing you should totally check out Robin Spainhour's presentation about Mock objects in Objective-C. Lot's of good stuff in there on how to test your code with the help of mock objects.

Wednesday, December 22, 2010

iOS Unit Testing: Loading Bundle Resources

When writing unit tests I often include files containing test data. Loading files that are included in the project as bundle resources is easy using the NSBundle method pathForResource:ofType.



This does not work when running the unit tests in the test target. It's the mainBundle part that breaks the code. From Apple's documentation

Returns the NSBundle object that corresponds to the directory where the current application executable is located.

It might be that the unit test target does not have an application executable and that's the reason it doesn't work. However, one small change to the snippet above is enough to be able to load bundle resources from within a unit test target. Change [NSBundle mainBundle] to [NSBundle bundleForClass:[self class]]

Another way to load resources when unit testing is presented by August Lilleaas in iOS unit testing Tips & Tricks.

Wednesday, November 3, 2010

Presenting a modal view controller

In this post I will look a two approaches on how to present a modal view controller in iOS: using a delegate and using blocks. The idea in both cases are that you want to get a result from the modal view controller and act differently depending on what the response is. E.g. knowing if the user touched cancel or save.

The example application is a very simple book library. The application has two screens, one screen that lists all books and one screen for entering a new book.

Book Library List ViewBook Library New Book View

When the program starts it's the RootViewController and its UITableView that gets displayed. When the user taps the Add button a instance of BookViewController is presented modally. If the user taps Save the book should be saved to the database and the BookViewController dismissed. If the user taps cancel the BookViewController should just be dismissed. There is a design decision that the BookViewController should not handle any database access.

Both projects are based on the Navigation-based Application template and uses Core Data for storage.

Delegate

The delegate pattern uses a protocol so the BookViewController can inform the presenter wether the user tapped Save or Cancel. The relevant parts of the interface definition looks like:

When presenting an instance of the BookViewController the code looks like:

This is the approach I normally use when presenting a modal view controller. I like the delegate pattern but it has some drawbacks, especially the need for a protocol. The presenter, the RootViewController in this case, needs to implement the protocol. I also almost always follow the pattern that Apple uses for delegates by having the sender as the first argument of the delegate method. This means that each view controller that uses this pattern also needs a matching protocol.

The code for this project can be found on github.

Blocks

To get around the need of creating and implementing protocols when presenting modal view controllers I decided to try and see if it was possible to use blocks instead. Which it was. The relevant parts of the interface definitions looks like:

Now when presenting an instance of the BookViewController the following code is used.

The code for the blocks project can also be found on github.

Discussion

At the time of writing this post I have not used the blocks approach to present a modal view controller other than in the test project above. I like that I don't have to implement a protocol when I want to present a modal view controller. This also means that a modal controller can be reused in an easier way if, for any reason, you need to have a different outcome depending on if an item is added or updated.

In this case there is no practical use for supplying the BookViewController in the call back. Which means that in blocks case the BookViewControllerResponse can be simplified to

typedef void(^ControllerResponse)();
and reused. I will have to explore this more to see if it actually is useful.


Tuesday, October 19, 2010

How to ask for a review, the bad way and the good way

I understand that the App Store is a tough market place. Unless you are on any of the top lists you might as well not exist. It is also hard since bad reviews, that you as the developer can't reply to, can lead to people not buying your app. So, what do you do?

In a recent update to the wikipedia reader Articles (to version 1.3) the following could be read in the description.

"If you like Articles, please rate it 5-stars in iTunes every time an update comes out! As always, your 5-star iTunes ratings and reviews keep the updates coming!"

I also got a similar request, with the same kind of concealed threat after buying the game Cut the Rope. I better go and give the app a 5-star review if I want to see the updates coming.

There is nothing wrong with asking for a review. There is also nothing wrong explaining the benefits of a good review. There is however not ok to ask for a review with a concealed threat as the case is for Articles and Cut the Rope (Both are high quality apps that I enjoy). Compare that to how Dan Benjamin asks for a review on the latest episode of The Pipeline:

"...if you enjoyed this episode, please consider rating this show on iTunes. It is the best way to help new listeners find out about the show."

Did I go and rate the show? Yes I did! Did I give it a 5-star rating? Yes I did! Would I have done the same for Articles and Cut the Rope if they had ask in a similar fashion? I believe I would.

Another way to keep the potential bad reviews and ratings out is to price your app accordingly, as Manton Reece did for his iPad app Tweet Library. An approach I find much nicer.

Monday, October 18, 2010

iTunes Apps: Check for Updates

The process of updating the apps of your iOS device is not as Apple like as I would expect. I find the use of modal dialogs to inform the user about the result of the Check for Update operation a bit obtuse.
After clicking Check for Updates one of two things happens, ignoring any errors. Either there are updates, in which case the following dialog is presented:
iTunes.png
In case there are no updates, iTunes informs the user via:
iTunes.png
A better solution would be to present the user with the Updates available page if there are updates. If there are no updates available iTunes could inform the user using the led-display at the top, just as when informing that a sync operation has been completed.
itunes app updates.png
This way the modal dialog can be removed.