Working with blocks

In Mac OS X 10.6 and iOS 4, Apple added blocks to Objective-C. When I first started looking at them because various APIs used them, the syntax confused me, and I pretty much ignored them as I was still doing work that ran on iOS 4 and Mac OS X 10.5.

This spring, all my projects moved to iOS 4 and Mac OS X 10.6 as the minimum requirements, so I took another pass at learning blocks. This time, however, I could actually use them and read all I could about them. The more I started looking at them, the more I became enamored with them. I started using blocks in my own APIs and just finished rewriting a significant chunk of code using blocks. Using blocks has made my code more readable and has greatly simplified certain aspects of our app.

One of my co-workers cautioned me to not use blocks just because they were the shiny new tool which I admit was what I was looking at doing. However, after using them, we found that using blocks was pretty much vital to making our code more readable.

For developers that aren’t familiar with blocks, I’d suggest learning them. With most iOS apps having a minimum OS of 4.0, there is no reason to avoid them.

The end of MovieConverter

It was just over 2 months ago when I released MovieConverter to the world to fill a gap where iMovie for iPad wouldn’t import videos from certain video cameras including my Sony Cyber-Shot DSC-WX9. I had originally came up with the idea for MovieConverter back when I got my iPad 2 and started playing with iMovie. I worked on MovieConverter over the summer and finally released it.

When I installed iOS 5 on my iPad 2, I found that iMovie imported more videos than before, but still not ones from my WX9. I made a few minor updates to MovieConverter to get it working better on iOS 5 and pushed it out the door. I got back from vacation the day after iOS 5 got released to the public and quickly updated everything including iMovie. The iMovie 1.2.2 notes said it added support for importing video from additional cameras.

Much to my delight and dismay, the videos from my WX9 imported into iMovie without MovieConverter. I immediately updated the MovieConverter description to say it may longer be needed and dropped the price to free so that no users would be pissed at me for writing a “useless” program.

From an iMovie user point of view, this is great news. I didn’t write MovieConverter for fame or fortune, but it was nice to get a little money from it.

Oh well, now I have to come up with another idea that will have a little more than 2 months on the app store.

MovieConverter available on the App Store

I’m pleased to announce that my MovieConverter app is now available on the iOS App Store. The app is designed for iPad users that want to import and edit video that was taken with a compact digital camera in iMovie.

The premise is pretty simple, but I think it is a huge help to those that don’t want to travel with a laptop and want to edit video.

While I don’t expect to become a millionaire on this, I do hope to sell enough copies to go out to dinner a few times!

Thanks Apple for the fast turnaround on approving this! Total time less than 9 calendar days from initial submission.

Another Lion change wreaking havoc

One common practice when subclassing a class is to use an application specific prefix so that if Apple adds a similar class in the future, it doesn’t conflict. For ReceiptWallet, I always used RW. One of the classes I subclassed was NSTextView so that I could draw text in gray when no text is entered. This is similar to NSTextFieldCell’s setPlaceHolderString method. I named my member variable placeHolderString and added a property. The code worked fine on Snow Leopard, but when it was run on Lion, we had reports that the placeholder text was drawn twice and blurry.

It appears that Apple added this property to NSTextView in Lion, but didn’t document it. I tried lots of different tactics to fix it, but decided the easiest thing to do was to rename my member variable/property. That worked perfectly and remains backwardly compatible.

So despite my best effort to keep my changes in my own namespace, there was no way for me to anticipate or detect this kind of change.

Lesson learned.

Bit by API Changes

Mac OS X Lion has changed some of the internal workings of various APIs and as I don’t work much on Mac apps, I didn’t care too much. However, one app I work on got bit by this pretty hard. In various places in the NSDocument based app, I called:

[self saveDocument:self];

This, I had assumed, was a synchronous call and then proceeded to make calls after that based on the fact that the call succeeded. Up until OS X Lion, things seemed to work fine. However, with Lion, this call seemed to cause problems and after reading the header file for NSDocument, I instantly realized the issue:

/* The action of the File menu's Save item in a document-based application. The default implementation of this method merely invokes [self saveDocumentWithDelegate:nil didSaveSelector:NULL contextInfo:NULL].
*/
- (IBAction)saveDocument:(id)sender;

So I was tricked into thinking there was a synchronous call and got bit by it. So I’ve fixed the code to use a callback and things seem to be working better. While I should have been using the asynchronous call all along, I don’t recall if it existed in OS X 10.4 when I first wrote the program.