Archive for the 'programming' Category

Most subclasses add instance variables. Objects initialized using initializer methods inherited from superclasses will only be partially initialized. Therefore you should override all initializers to avoid accidentally creating a partially initialized object. However unless there is a reasonable default for all instance variables this may not be possible. In such cases, one usually overrides the initializer by a method returning nil. However it is difficult to debug nil-errors. A better solution is to override the method to invoke doesNotRecognizeSelector: Since _cmd is always the current method’s selector one can use the same method body. For instance:

Mac Tech just published my article on call stack logging which lets you see which function calls led to my NSLog replacement being invoked. The nice thing is that it works for C, C++ and Objective-C unlike most of the solutions you see elsewhere. The source code should show up on their ftp site some time soon. With few developer magazines surviving (Dr Dobbs webified, BYTE gone), I’m glad Mac developers still have a print magazine to read.

Changing file-formats is far from free. It fractures your user base as your users find they cannot share their documents with their friends. It makes it difficult for you to regression test your code. And it dissuades third parties from supporting your file-format, because you’re giving them more work each time you change. Overall changing file-formats should be avoided where possible. How then can you extend your application?

Future proof your file-formats!

I try to keep my file-format forwards compatible: the same file should work with older versions of my software. This makes it easier to find bugs that I may inadvertently have added: I can regression test against an older version of the software.

I use a file-format that lets the Application store but not use the fields it does not understand. There are many such solutions: SQLITE database, Trees, XML, python pickles… The reason to store fields one does not understand is that one can save them back out later.

For example consider an HTML document. Even if your HTML editor does not know what the “blink” tag means, it can remember the fact that that there is a “blink” tag around the text over there. Even if you edit the text within the blink tag, it can make reasonable guesses about grouping. Of course if you delete the text and type it back in, the blink tag will be gone. But most of the time you don’t just lose your formatting because a colleague used a different tool to edit your file. The key idea here is that you can use an extensible hierarchical data format to keep things associated with their attributes.

Keep the conversion code separate!

Sometimes, to simplify the main application’s code, it does makes sense to change file-formats. In that case, write a bidirectional converter. A version field in the file-format specifies (by naming convention) the converter to use so that the App when encountering a file of a different file-format can figure out the chain of conversions it must apply to get something it understands.

Now if you downgrade, you’re in almost the same position as your friend who never upgraded: your application can’t read the new format files. There is however a difference: as part of the upgrade process a bidirectional converter was added. It does not need to be removed on a downgrade. Because the the older version of the application knows how to figure out which converters to call, it will just find them and call them.

Note that because the original file-format is extensible, it’s possible for the bi-directional converter not to throw away any data. Similarly because the oldest version of the app stores the stuff it does not understand and saves it back out again, changes made by a co-worker with an older version of the software should cause little data loss.

Additional benefits of independent converters

Because you have independent converters you can earn bonus points with people who have not yet been able to upgrade. You can give or sell them the tool to convert the files. The tool can even advertise the features they’d get by upgrading.

You benefit because your code is simpler. The application code is simpler because it only knows its native file-format, the converter’s code is simpler because it’s focussed on one task. You also benefit because it’s easier to require a new base OS for your next version without fracturing your user-base.

Of course writing writing a converter is a pain, and a bidirectional one even more of a pain, but as I said in the beginning changing file formats should be avoided. Writing a bidirectional converter forces you to consider more cases, leading to a better upgrade converter. Furthermore you can reduce the pain for third parties by giving or licensing your converter to them.

What about standard file formats?

I think the same idea of independent converters can be applied, although it may not be possible to keep the additional information known to later versions of the file-format in earlier versions of the file format.

It contains a few bug fixes, and a crash reporter to help people report bugs.

The biggest change is that Input Managers are disabled within Find It! Keep It! by default. They’ll still work in your other applications.

Why? All but one of the reported crashes at launch were due to Input Manager conflicts: 50% of all reported bugs! Understandably, if a crash is your first experience with Find It! Keep It!, you’ll assume Find It! Keep It! is at fault.

Contacting the author of every Input Manager that fails to ask them for a fix isn’t ideal: my users need to tell me what crashed and work with me to isolate the fault, and the Input Manager author needs to be willing to fix the problem. In the real world, most users will just give up.

Furthermore, in many cases, Input Managers are targeted at a specific application. For instance, Safari Tidy targets Safari, Chax targets iChat. At best they are harmless when loaded into other applications. At worst they’ll crash them.

So what if you actually want to access an Input Manager’s functionality from within Find It! Keep It!? I provide a Preference Panel that allows you to enable any of your Input Managers. When loading a new combination of Input Managers, Find It! Keep It! will step you through the process to help isolate crashes on load. It also disables any Input Manager it recognizes as having crashed on load, and restarts without it.

Hopefully, this is the best of all worlds: the ability for users to customize their systems without the penalty of instability.

I would like to see Apple providing stronger system controls over Input Managers, and other customizations: the user should always be in control. In particular Input Managers make adware trivial to implement on the Mac. Apple could improve overall user experience by requiring users to explicitly go to a preference panel to allow a given Input Manager to load into a given application.

Spam Filters

Again it seems some spam filters are preventing people from receiving the download information… No one has been turned away from this beta, so if you requested it, please tell your spam filter that mail from ansemond.com is not spam. If you email me again, I’ll be happy to send you the information a second time.

Bugs

Input Managers, aka Plugins: Two crashes on launch were due to third party plugins

Cocoa: One bug seems to be that Cocoa gives me the wrong information (weird!)

Flash plugins disabled: I believe this is due to a misconfigured computer, but I need to dig into it further.

Rosetta: One report of Rosetta crashing on an Intel Mac, and thereafter Find It! Keep It! would not start again. To deal with this case I made a small program for Intel Mac owners that restarts Rosetta before starting Find It! Keep It!

Overall observations

Because people who are willing to run betas are people who try new things, they run plugins I’ve never even heard of, and have interestingly configured computers. Beta testing is trial by fire for the software being tested!

People downloading the tool use a wide spread of browsers: 60% use Safari, 21% use Firefox (1.5 & 2.0), followed by OmniWeb, Camino, Opera and something called iGetter

A few people seem to be hoping that it will work on 10.3.x… I’m afraid it won’t.

I finally received my Intel Mac, and was able to test Find It! Keep It! on an Intel Mac. It works fine under Rosetta, which is very encouraging. A previous test failed badly. Apple’s fixes in 10.4.8 must have done the trick…

The beta was ready to go out on Monday, but before letting it out I was given the advice to add some form of protection. Apparently piracy of Mac shareware is a thriving industry: Spending less that 10 minutes searching, I found licenses to every piece of shareware I know!

Wil Shipley doesn’t believe it’s a big deal, as pirates would not buy in the first place, but could be the software’s loudest advocates. To some extent, I agree with him.

On the other hand, Colin Messitt makes a very convincing case that unprotected software does not sell well. Having spent a year and my savings working on this tool I cannot afford to lose 4/5ths of my customers.

So… I’ve been adding encryption and registration code to Find It! Keep It!. Many simple solutions violate people’s privacy or are annoying. For instance, I could tie each license to a single machine. But then, people could not upgrade easily. But doing it right takes time… Once this hurdle is over, I’ll release Find It! Keep It!.

(gdb) b myFuncBreakpoint 1 at 0×900107a8(gdb) commands 1Type commands for when breakpoint 1 is hit, one per line.End with a line saying just “end”.>bt>c>end(gdb)

The biggest problem with the web is, as Arthur C Clarke said: “Why should I go to the Niagara Falls when all I want is a glass of water?”. The same can be true of overly feature rich tools. Having spend a few fruitless hours googling for this, I have been resorting to piping python scripts into gdb.

Just for fun, I wrote up some of my own ideas that I would like, but do not have the time to code myself.

After considering the developer’s view, it’s interesting being on the user’s side of the equation: I can leave the worrying about how it could be done to someone else and focus on the core idea. But on the other hand, I’m concerned that if the idea does win, the programmer might screw it up (see it differently).

I hope one of my ideas gets chosen. It could be quite an interesting experience. And I could use a MacBook myself

Like other independent software developers I’ve been following My Dream App with interest. It’s a purple cow: remarkable because it is different, allowing users to define the application they would like.

While the competition is a purple cow, I’m not sure that the offspring will also be purple: the final choice of the application resides with the participants rather than with the developers. Seth points out that remarkable products don’t survive focus-groups or committees. So, what’s in it for the developers? Writing a great application takes time, dedication and passion, which only occur if the developer is truly sold on its idea. If the result is lackluster, it will not compensate the developers for their time…

However the experiment is definitely worth watching: it goes against the received wisdom that users define the functionality they need but not the form the solution will take. For instance, Steve Jobs said“It’s really hard to design products by focus groups. A lot of times, people don’t know what they want until you show it to them”. Joel (on Software) said” Customers Don’t Know What They Want. Stop Expecting Customers to Know What They Want”. Steve McConnell says in Rapid Development that users don’t know what they want. Will the developers implement what the winners say they want? or change the ideas to be their own?

The only other comment I’d make is that I’ve had many of the ideas presented on the Dream App forum. Unsurprising I guess, given how many of them turn out to have already been implemented. Perhaps I need to come up with a “cool winning idea” of my own: I need an Intel Mac Book on which to test Find It Keep It !