There’s a new Objective-C pattern I’ve been experimenting with lately, which looks like this:
This syntax probably isn’t familiar to Objective-C programmers, but it’s actually simple. It’s a trick that takes advantage of a compiler extention where putting a variable by itself as the last line within () braces acts as “returning” that variable, meaning you can use the whole expression as an assignment.
What’s the point? Chances are you’ve worked on an iOS app or two where some big controller class had a viewDidLoad method that’s grown out of control. The kind of class that’s managing a dozen views, each with their own content, setup, positioning and so on. In these classes the viewDidLoad method can be hundreds of lines long, impossible to quickly read and parse, and require refactoring for even small changes.
The advantage of this syntax is that it wraps each assignment into a neat little bundle, no matter how much extra work is related to it. Temporary variables, subviews, configuration and whatnot all live within the scope’s braces, so it’s easy to see at a glance what code belongs to each specific object. You can give temporary variables nice names too, since they all live within their own scope. Ever have a method where you have to name things like passwordFieldFrame, confirmPasswordFieldFrame, …? Now each of those CGRects can just have the nice, short name “frame” without worrying about stepping on the toes of another object.
There’s an argument to be made against this syntax, and I’m not completely sold on the idea. In an ideal world you’d want to split these view controllers into more managable subcontrollers, instead of trying to pretty up the mess. It’s also a little hacky, relying on a language feature that’s not intended for this purpose. But despite these problems I still kind of like what it does. It’s hard to say no to anything that makes code more manageable and easy to read.
If you’re the type of developer who’s always digging into the Cocoa frameworks to find the stuff that makes your life easier, you’re probably using NSCache. It’s a great class after all. Just store your temporary objects in an NSCache instead of an NSMutableDictionary, and you won’t have to worry about memory usage. Right?
Not exactly. A recent conversation on Twitter reminded me of my own experiences working with NSCache and memory warnings. Although it’s natural to expect NSCache to clear itself in response to a memory warning notification, this isn’t what actually happens. NSCache does automatically evict objects, but this behavior is very unclear and undocumented. In short, don’t depend on it. It’s possible for your app to receive memory warnings, and even crash due to low memory, all without NSCache lifting a finger to help. Instead, keep doing what you’ve always done. Register for low memory notifications and manually release any objects that aren’t essential, whether they’re stored within NSCache or otherwise.
There’s nothing wrong with using NSCache, but until the docs say otherwise don’t count on it to do the work for you.
I’ve had this post cooking for a long time, and I think it’s ready to unveil. If you code Objective-C, this is going to offend you and that’s good. If you aren’t offended, then you don’t care, and that’s bad.
This list isn’t about stylistic things like which line new braces go on (new ones, duh). This list is about potential problems with the code you’re writing on an objective scale. So let’s get started.
Read more on Ash Furrow’s blog. I admit, I’m guilty of a few of these. Hopefully number seven, not using automated testing, will soon be crossed off my list. I’ve experimented with it in the past, but still haven’t adopted it on any of my shipping Cocoa projects.
Jeff Atwood recently wrote about copy and paste coding, and those small, frequently reused code snippets that pop up at every programming blog or website.
To me, the most troubling limitation of copypasta programming is the complete disconnect between the code you’ve pasted and all the other viral copies of it on the web. It’s impossible to locate new versions of the snippet, or fold your features and bugfixes back into the original snippet. Nor can you possibly hope to find all the other nooks and crannies of code all over the world this snippet has crept into.
What I propose is this:
Attach a one line comment convention with a new GUID to any code snippet you publish on the web. This ties the snippet of code to its author and any subsequent clones.
I’ve been idly thinking about the same thing lately, especially since I’ve started using services like gist.github to share and view small code snippets. A good example is a category on NSBezierPath to add rounded rectangles, which I remember copying from someone 5 or 6 years ago when I first started with Cocoa. If I was using this in a project today there’s no way I would remember who it originally came from, or be able to tell (except accidentally) that Leopard added the same thing when it was released and now I don’t need to use the snippet at all.
I really don’t know if GUIDs are the best (or even a workable) solution. I don’t have anything against the idea, but how can you enforce it on every blog, code sharing website, programming forum, and so on? Still, when I think about a programmer’s dream world I imagine my IDE tagging these snippets with contextual information, popping up a window with text from a blog post just like it does with autocompletion.
Runner’s Log uses a license file for registration, instead of a typical 20 digit serial number. With a license file, instead of sending users a code they type or paste into your application, you send them a file that contains the serial number along with any other registration information. Usually this is just a plain text file, although it doesn’t have to be.
Lately I’ve been thinking about the advantages and disadvantages of one method versus another. Here are the major points I came up with.
- When done correctly, license files can be easier than typing in a serial number. Just drag the file onto your app, or double click it. On the other hand, if you only require one field for your license key, and handle copy/paste correctly, serial numbers are not that much harder.
- You can include whatever information you want in you license files. You don’t want to force the user to type in their name, email address, transaction number, but there’s no reason not to include these when you generate the license. It’s good to make sure to associate a license with a real life name or email address, to discourage casual piracy.
- License files (should be) very secure. I’m not saying you can beat software piracy, don’t believe anyone who tells you you can. What you can do, is prevent someone from creating a serial number generator for your app. Unlike shared keys or cracked copies, which you can fight by releasing updates and blacklists, a serial number generator can be especially damaging. As far as I know, using OpenSSL it’s possible to create a licensing scheme that can not be beat by serial generators.
- License files don’t always fit with other company’s distribution models. Right now I’m talking with a company about localizing and selling Runner’s Log in Japan, both online and in a boxed software bundle with other applications. Although I’m sure I’ll work it out somehow, they assume applications use a serial number which can be sent via email or printed out. I would guess that some of the other promotional bundles, like MacZot or Mac Heist, work the same way.
- License files can go against the way users expect applications to work, or interfere with the way they store license codes for future use. I haven’t had any specific complaints, but it’s possible some people might be annoyed.
- It takes a little more work to implement license files. You need to associate the .applicense extension with your application, implement methods for loading external files, and make sure your online store can correctly send attachments in the registration email. In my case, I also ran into some unicode text encoding bugs I had to rush to fix. None of these require big investments in time; what I’m getting at is that the little things add up, and I don’t know any developers who wished they had more on their plate right before shipping 1.0.
No matter which method you use, there’s room to make your application stand out if you put in enough effort. I remember seeing a mock-up of a license file that was actually a generated .gif or .png image. The image looked like a key card, complete with the user’s information and the license key shown as a barcode (the actual license data could be stored in embedded metadata or headers for your application to read). If you use license codes, instead of random numbers and letters you could use a series of four or five letter english words.
For the most part, license files have worked well for Runner’s Log. However, there has been a small amount of overhead that I would have rather avoided. I’m going to keep this in mind for future projects; hopefully this will help new developers who might be in the same position I was.
Fundware is just one announcement from United Lemur, a company founded recently by engineer Mike Lee. The idea is for new software companies to start out with a small (but high quality) offering, such as an iPhone App. Visitors to Fundware decide to purchase the application not just on its own merit, but also on the potential of the company itself. If successful, the revenue from Fundware will give the new company capital they need to get off the ground and start producing great full-sized applications.
Most “indie” Macintosh software companies (including mine!) are started with free time and a savings account, not investment venture capital or loans. This seems like a great way to help out developers who have great ideas, but lack the time or money to implement them.
The first featured application is Puzzllotto, United Lemur’s own initial iPhone offering. Apart from being the driving force behind some great applications, Mike Lee has some lofty goals for United Lemur and how it will impact the Mac software development community— I hope he’s successful.
Mike Ash on Cocoa Initializers. Great explanation of why you should use the debated
self = [super init] in your Objective-C initializers. For the other side of the argument, read Wil Shipley’s take.
I know it’s old, but last week I finally got around to watching Cabel Sasser’s C4 presentation.
Earlier this year I gave a talk (my first public presentation ever, actually!) at Johnny Rentzsch’s intimate and engaging C4 conference in Chicago. Despite nervousness, it was really great fun. We had just recently finished Coda, and with one hour to fill and a lot of Coda-related things still swirling around my mind, I pretty much just started talking. What followed was a whole lot of hyper-warp thoughts about all things Panic.
The presentation is great; lots of insight into the visual design process at Panic, and some of the challenges of developing Coda.
One of the more interesting parts was at the very end of the audience questions, where Cabel talks about the differences between developing a “big” application (Coda) and working on several tiny ones. Apparently the small applications each had enough feature requests and bugs that they took nearly as many resources and time as creating a larger application, only the smaller price tag meant only a fraction of the profits.
The iPhone SDK has finally landed, bringing with it real Exchange support, WPA2 and other goodies. You can watch the announcement event here, or read highlights and commentary at Daring Fireball.
Although I don’t own an iPhone (yet), I did download the SDK and look forward to playing with it. My feelings about the price structure seem to be about the same as what most other developers are thinking. The $99 listing fee is no big deal. In my experience, even semi-popular freeware applications can earn back more than that through donations. The 30% Apple commission is high, but at the same time the iPhone is opening up an additional revenue source that will augment existing sales. It’s also a really neat, fun platform to develop for.
As a user, I am a little concerned about iPhone applications that are built off of their desktop alternatives. For example, if I buy a license for Delicious Library 2, will I have to pay an extra $20 for an iPhone version (assuming one is eventually released)? Will the iPhone version be free, but intentionally crippled so you need or want the full desktop version? It would be great if the iPhone version could be unlocked with a desktop serial number, but it seems like this won’t be possible. Maybe developers will be able to create coupons that will work in the iTunes store, but I haven’t heard anything about that.
I’m going to buy an iPhone eventually, I’m considering holding out until the next revision. It seems like it June would be a perfect time to release a second generation iPhone along with the new firmware update.