Indie app milestones part one

In the precious and scarce spare time I have around my regular contracting endeavours, I’ve been working on my first indie app. It reached an important stage in development today; the first time where I could show somebody who doesn’t know what I’m up to the UI and they instinctively knew what the app was for. That’s not to say that the app is all shiny and delicious; it’s entirely fabricated from standard controls. Standard controls I (personally) don’t mind so much. However the GUI will need quite a bit more work before the app is at its most intuitive and before I post any teaser screenshots. Still, let’s see how I got here.

The app is very much a “scratching my own itch” endeavour. I tooled around with a few ideas for apps while sat in a coffee shop, but one of them jumped out as something I’d use frequently. If I’ll use it, then hopefully somebody else will!

So I know what this app is, but what does it do? Something I’d bumped into before in software engineering was the concept of a User Story: a testable, brief description of something which will add value to the app. I broke out the index cards and wrote a single sentence on each, describing something the user will be able to do once the user story is added to the app. I’ve got no idea whether I have been complete, exhaustive or accurate in defining these user stories. If I need to change, add or remove any user stories I can easily do that when I decide that it’s necessary. I don’t need to know now a complete roadmap of the application for the next five years.

As an aside, people working on larger teams than my one-man affair may need to estimate how much effort will be needed on their projects and track progress against their estimates. User stories are great for this, because each is small enough to make real progress on in short time, each represents a discrete and (preferably) independent useful addition to the app and so the app is ready to ship any time an integer number of these user stories is complete on a branch. All of this means that it shouldn’t be too hard to get the estimate for a user story roughly correct (unlike big up-front planning, which I don’t think I’ve ever seen succeed), that previous complete user stories can help improve estimates on future stories and that even an error of +/- a few stories means you’ve got something of value to give to the customer.

So, back with me, and I’ve written down an important number of user stories; the number I thought of before I gave up :-). If there are any more they obviously don’t jump out at me as a potential user, so I should find them when other people start looking at the app or as I continue using/testing the thing. I eventually came up with 17 user stories, of which 3 are not directly related to the goal of the app (“the user can purchase the app” being one of them). That’s a lot of user stories!

If anything it’s too many stories. If I developed all of those before I shipped, then I’d spend lots of time on niche features before even finding out how useful the real world finds the basic things. I split the stories into two piles; the ones which are absolutely necessary for a preview release, and the ones which can come later. I don’t yet care how late “later” is; they could be in 1.0, a point release or a paid upgrade. As I haven’t even got to the first beta yet that’s immaterial, I just know that they don’t need to be now. There are four stories that do need to be now.

So, I’ve started implementing these stories. For the first one I went to a small whiteboard and sketched UI mock-ups. In fact, I came up with four. I then set about finding out whether other apps have similar UI and how they’ve presented it, to choose one of these mock-ups. Following advice from the world according to Gemmell I took photos of the whiteboard at each important stage to act as a design log – I’m also keeping screenshots of the app as I go. Then it’s over to Xcode!

So a few iterations of whiteboard/Interface Builder/Xcode later and I have two of my four “must-have” stories completed, and already somebody who has seen the app knows what it’s about. With any luck (and the next time I snatch any spare time) it won’t take long to have the four stories complete, at which point I can start the private beta to find out where to go next. Oh, and what is the app? I’ll tell you soon…

Posted in Business, cocoa, macdevnet, metadev, usability | 2 Comments

On XP mode

This is a reply to @gcluley, who linked to this ZDNet story (which in turn took its quotes from Sophos Podcasts).

The second most crazy thing about the entire “XP mode” issue in Windows 7 is that the feature is entirely unnecessary. Corporate customers of Windows are already, for the most part, comfortable with managing virtual Windows desktops through third-party products with much better management options or at least have trialled such products. Home users of Windows just take whichever version is pre-installed when they buy the PC and if it means buying new versions of some apps, that’s what they do. They’re used to it. The group of people who could benefit from XP mode – people with a strong need for app compatibility with XP but with no experience of virtualisation – just doesn’t exist.

The very existence of the XP mode feature is a microcosmic example of the way Ballmer has been running Microsoft – if there’s a market out there that MS isn’t in, MS needs to be in it pronto. Bing, Morro, Web-Office, Zune and now virtualisation are all testament to the inability of Microsoft to concentrate on what it does. What Microsoft really does is to sell two things; an enterprise computing environment and an OEM software distribution. Forget that Windows and Office are accounted as two separate products; MS sell Windows+Office to businesses and Windows to computer makers.

Now the interesting question to ponder is which of Microsoft’s (real or perceived; remember they aren’t necessarily in this market) competitors the “XP mode” feature is a response to. My interpretation is that it’s not actually VMware and its ilk at all – Microsoft is once again responding to nonexistent competition from Apple. Boot Camp and the third-party desktop virtualisation offerings on the Mac (including, without hint of irony, VMware) let users use OS X as their shiny new OS with an “XP mode” of sorts for legacy applications. I think what Microsoft are trying to do here is to show that Windows can be the new shiny with XP as the legacy mode, and are therefore positioning XP mode as a counter to the fictitious competition from Apple. Oh, and if you don’t believe me when I say that the competition from Apple doesn’t exist – Apple sell all of the premium computers while Microsoft take the aforementioned corporate and OEM markets.

OK, so if that was the second most crazy thing about XP mode, what is the most crazy thing about XP mode? It’s also that the feature shouldn’t exist. Windows has always had a problem with segregating distinct services which other operating systems don’t suffer from. While Microsoft’s avoidance of this issue has allowed a whole new software industry to spring up around it, the fact that they need to start a second copy of Windows just to get some applications running in Windows 7 doesn’t give me much hope for the future.

Posted in whatevs | 2 Comments

The next million-dollar iPhone application

I’m constantly surprised by questions such as this one. They invariably go along the lines:

I heard that I need to get a Mac to do iPhone development. I want to do iPhone development but do I have to buy a Mac? Is there any other way to develop iPhone software?

If the projected sales for your app don’t meet the cost of a new computer, whatever platform you’re developing on, it’s time to get a different idea for your app. I speak with the smug self-confidence of one who has yet to get his own app within smelling distance of the store.

Posted in whatevs | 4 Comments

A rap upon the noggin

When a patient may be concussed, it’s common for parademics to ask simple, topical questions to determine whether the patient is confused. Questions such as “who is the Prime Minister”?

I think somebody may have knocked this poor spammer upside the head (emphasis is mine):

Lloyd’s TSB Group plc
25 Gresham Street
London EC2V 7HN

Greetings,

Following the recent announcement by the Chancellor of the Exchequer, Gordon Brown that all assets in accounts that have been

dormant for over 15years be transferred to the Treasury i send this mail to you.

There is a dormant account in my office,with no owner or beneficiaries. It will be in my interest to transfer this assets

worth 20,000,000 British pounds to an offshore country. If you can be a collaborator/partner to this please indicate interest

immediately for us to proceed.

Remember this is absolutely confidential,as i am seeking your assistance to act as the beneficiary of the account, since we

are not allowed to operate a foreign accounts. Your contact phone numbers and name will be necessary for this effect.
I have reposed my confidence in you and hope that you will not disappoint me.

My Regards,
Jim McConville
Lloyd’s TSB Group plc

Posted in whatevs | Leave a comment

Website relaunch!

Today I have re-launched Thaes Ofereode to focus on my new role as an independent Mac boffin. I really like the new design, which was created by the ever-delightful Freya.

edit: Gecko doesn’t understand the CSS media selector I was using to provide the iPhone CSS. I’ve therefore reverted the iPhone design until I can find a way to get Firefox to suck less.


The one thing I added to her design was a more iPhone-friendly look. For those of you without iPhones, the screenshots demonstrate how the mobile version will appear. For those of you who are CSS experts, the following will probably be rather dull but for those like me who know enough to be dangerous but no more, here’s how it’s done.

The three-column layout works really well on the desktop, but the iPhone has a tallscreen-oriented display so not much space for horizontal layout. I therefore chose to put the leftmost, menu column underneath the main content on each page, so iPhone users get to see the heading and then the meat and potatoes. If they are interested enough to get to the end, they’ll see the links to the rest of the site.

The links, btw, are just paragraphs with a border, a lot of padding and the magic -webkit-border-radius providing the roundy edges; no messing with JavaScript and funny part-circle images.

So, the third column? Well those impressive-looking widgets can’t be displayed on the phone anyway, and would be a bit out of place so they’re gone for the moment with the mobile CSS. I may code up some JavaScript replacements soon enough, but I’ll need to find somewhere else for them to go. In the meantime, I know you read my blog because you’re here, and there are many apps which can help you follow me on Twitter.

Posted in whatevs | Leave a comment

Next CocoaHeads Swindon meet!

So for those of you who didn’t manage to enjoy the glories to be found in the town that was the inspiration for one of Legion’s more colourful adventures,[] next Monday, the 3rd of August, offers yet another once-in-a-monthtime opportunity! As ever, the location is in (or just outside) the Glue Pot, a strong man’s stone’s throw from the Swindon train station. This month’s meeting is a recap on QTKit, to allow those who weren’t there last time due to the reschedule to catch up on integrating QuickTime into their Cocoa apps.

[] What am I doing knowing quotes like that? Well, the clue is in the user name. When I was a student my UNIX username was leeg, clearly based on my real name. In short order, I was introduced as "He is Leeg, for he are many" and thus iamleeg.

Posted in whatevs | Leave a comment

NSConference videos

Scotty and the gang have been getting the NSConference videos out to the public lately, and now sessions 7-9 are available including my own session on security. The videos are really high quality, I’m impressed by the postproduction that’s gone in and of course each of the sessions I watched at the conference has some great information and has been well-presented. All of the videos are available here.

I’ve also put the slides for my presentation up over on slideshare.

Posted in cocoa, conference, macdevnet, security, Talk | Leave a comment

Coming very shortly…

This website will be the new home for information on Cocoa and Mac OS X security. But not yet! Please check back soon; in the mean time take a look at my homepage.

Graham.

Posted in Uncategorized | Comments Off on Coming very shortly…

Refactor your code from the command-line

While the refactoring support in Xcode 3 has been something of a headline feature for the development environment, in fact there’s been a tool for doing Objective-C code refactoring in Mac OS X for a long time. Longer than it’s been called Mac OS X.

tops of the form

My knowledge of the early days is very sketchy, but I believe that tops was first introduced around the time of OPENSTEP (so 1994). Certainly its first headline use was in converting code which used the old NextStep APIs into the new, shiny OpenStep APIs. Not that this was as straightforward as replacing NX with NS in the class names. The original APIs hadn’t had much in the way of foundation classes (the Foundation Kit was part of OpenStep, but had been available on NeXTSTEP for use with EOF), so took char * strings rather than NSStrings, id[]s rather than NSArrays and so on. Also much rationalision and learning-from-mistakes was done in the Application Kit, parts of which were also pushed down into the Foundation Kit.

All of this meant that a simple search-and-replace tool was not going to cut the mustard. Instead, tops needed to be syntax aware, so that individual tokens in the source could be replaced without any (well, alright, without too much) worry that any of the surrounding expressions would be broken, without too much inappropriate substitution, and without needing to pre-empt every developer’s layout conventions.

before we continue – a warning

tops performs in-place substitution on your source code. So if you don’t like what it did and want to go back to the original… erm, tough. If you’re using SCM, there’s no problem – you can always revert its changes. If you’re not using SCM, then the first thing you absolutely need to do before attempting to try out tops on your real code is to adopt SCM. Xcode project snapshots also work.

replacing deprecated methods

Let’s imagine that, for some perverted reason, I’ve written the following tool. No, scrub that. Let’s say that I find myself having to maintain the following tool :-).

#import <Foundation/Foundation.h>

int main(int argc, char **argv, char **envp)
{
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
NSString *firstArg = [NSString stringWithCString: argv[1]];
NSLog(@"Argument was %s", [firstArg cString]);
[arp release];
return 0;
}

Pleasant, non? Actually non. What happens when I compile it?

heimdall:Documents leeg$ cc -o printarg printarg.m -framework Foundation
printarg.m: In function ‘main’:
printarg.m:6: warning: ‘stringWithCString:’ is deprecated (declared at /System/Library/Frameworks/Foundation.framework/Headers/NSString.h:386)
printarg.m:7: warning: ‘cString’ is deprecated (declared at /System/Library/Frameworks/Foundation.framework/Headers/NSString.h:367)

OK so we obviously need to do something about this use of ancient NSString API. For no particular reason, let’s start with -cString:

heimdall:Documents leeg$ tops replacemethod cString with UTF8String printarg.m

So what do we have now?

#import <Foundation/Foundation.h>

int main(int argc, char **argv, char **envp)
{
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
NSString *firstArg = [NSString stringWithCString: argv[1]];
NSLog@"Argument was %s", [firstArg UTF8String], length);
[arp release];
return 0;
}

Looking good. But we still need to fix the -stringWithCString:. That could be just as easy, replacemethod stringWithCString: with stringWithUTF8String: would do the trick. However let’s be a little
different here. Why don’t we use -stringWithCString:encoding:? If we do that, then we’re going to need to take a guess at the second argument, because we’ve got no idea what the encoding should be (that’s why -stringWithCString: is deprecated, after all. However if we’re happy to assume UTF8 is fine for the output, let’s do that for the input. We’d better let everyone know that’s what happened, though.

So this rule is starting to look quite complex. It says “replace -stringWithCString: with -stringWithCString:encoding:, keeping the C string argument but adding another argument, which should be NSUTF8StringEncoding. While you’re at it, warn the developer that you’ve had to make that assumption”. We also (presumably) want to combine it with the previous rule, so that if we see the original file we’ll catch both of the problems. Luckily tops lets us write scripts, which comprise of one or more rule descriptions. Here’s a script which encapsulates both our cString rules:

replacemethod "cString" with "UTF8String"
replacemethod "stringWithCString:<cString>" with "stringWithCString:<cString>encoding:<encoding>" {
replace "<encoding_arg>" with "NSUTF8StringEncoding"
} warning "Assumed input encoding is UTF8"

So why does the <encoding> token become <encoding_arg> in the sub-rule? Well that means “the thing which is passed as the encoding argument”. This avoids confusion with <encoding_param>, the parameter as declared in the class interface (yes, you can run tops on headers as well as implementations).

Now if we save this script as cStringNoMore.tops, we can run it against our source file:

heimdall:Documents leeg$ tops -scriptfile cStringNoMore.tops printarg.m

Which results in the following source:

#import <Foundation/Foundation.h>

int main(int argc, char **argv, char **envp)
{
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
#warning Assumed input encoding is UTF8
NSString *firstArg = [NSString stringWithCString:argv[1] encoding:NSUTF8StringEncoding];
NSLog(@"Argument was %s", [firstArg UTF8String]);
[arp release];
return 0;
}

Now, when we compile it, we no longer get told about deprecated API. Cool! But it looks like I need to verify that the use of UTF8 is acceptable:

heimdall:Documents leeg$ cc -o printarg printarg.m -framework Foundation
printarg.m:6:2: warning: #warning Assumed input encoding is UTF8

exercises for the reader, and caveats

There’s plenty more to tops than I’ve managed to cover here. You could (and indeed Apple do) use it to 64-bit-cleanify your sources. Performing security audits is another great use – particularly using constructs such as:

replace strcpy with same error "WTF do you think you're doing?!?"

However, notice that tops is a blunter instrument than the Xcode refactoring capability. Its smallest unit of operation is the source file; refactoring only within particular methods is not quite easily achieved. Also, as I said before, remember to check your source into SCM before running a script! There is a -dont option to make tops output its proposed changes without applying them, too.

Finally tops shouldn’t be used fully automated. Always assume that you need to inspect the output carefully, don’t just Build and Go.

Posted in cocoa, nextstep, objc, openstep, xcode | 3 Comments

CocoaHeads Swindon tonight!

For those of you who’ve never explored the delights that the fine city of the Hill of Pigs has to offer, tonight offers an unparalleled opportunity. Come and sit in (or outside, weather permitting) a pub only a short distance from the railway station, and listen to Mike Abdullah speaking about WebKit. As always there’ll also be general NSDiscussion, and the occasional pint of beer. Maps etc. at our cocoaheads.org page.

Posted in cocoa, cocoaheads, webkit | Leave a comment