Is it Time for Metadata in Source Code?

It suddenly struck me how that programmers are deprived of metadata, compared to other computer users. Word processor users have tons of data about their documents, size, layout, fonts, colors, and it all travels with the document. Likewise Photoshop users have loads of metadata about the layers and objects and other stuff that makes up their image.

But what do programmers have? Nothing! Just plain text files. If you’re working in a command line environment, it’s nothing but text files, source files, make files, lists and include files. In an IDE it’s a little better, but the metadata is stored (probably in XML) in a proprietary format associated with a project or workspace.

I think it’s time for that to change. I think we need to find some way to mark-up source code so that it is more useful than just fodder for the compiler. Maybe layout  tags that tell the editor to display the source with your personal style of bracing and indentation. Maybe meta-tags for syntactic sugar that formats it the way you prefer. For instance, in Objective-C [foo setBar:bar] and foo.bar = bar; are the same thing. The second example, the dot syntax is a newer addition to the library. Some people don’t like the new syntax, so what if their IDE somehow knew this and converted the code? It’s all the same to the compiler, after all. But converted it in such a way that someone who preferred the dot syntax would still see the dot syntax and be able to write the dot syntax.

There’s many other things that meta data could do, like preserving revision information in the file, instead of in the VCS. Isn’t that what word processors do?

Maybe there’s a way to include the programmer’s documentation in the source, in a more useful way than just comments. Comments rapidly lose their meaning, and even location, as code changes. Maybe metadata could be attached to variables and functions, and travel with them, even with moving to other files where the functions are called.

I’m sure there’s a lot of other uses, and I’m sure there must be ways to implement these features in a standard way to work with any language, and any toolset.

I’m asking for feedback on this. What do you think? Is this the way of the future, or just needless complexity? How do you think it could work? What other features can you envision? Let me know!

Menu Magic

I was hunting around last night for the method behind this trick and I couldn’t really find it summarized in one place, so I thought I’d do it myself.

First, an example. Open the ‘Apple’ menu on your Mac. Now hold down the ‘alt/option’ key. See how some of the menu items change? Specifically, how ‘About This Mac’ changes to ‘System Profiler…’? This is all done with menu alternates, key equivalents, and key modifiers. But ‘About This Mac’ has no key equivalent. Wha happen?

Let’s start with menu alternates. A menu alternate is just a menu item marked as an ‘alternate’ to the menu item above it. This is just a tick box in Interface Builder, but that’s not all that is required.

The connection between the two is that they share a key equivalent, but the alternate has an extra modifier. So if you have one menu item with key modifiers ⌘ M and the one below it has ⇧⌘ M, then the first one will normally appear, but if you open the menu and hold down the shift key, the other menu item will appear, in place of the first.

So that’s the trick. Make the first menu normally, with no modifiers. Make the second menu item, make it an alternate, and give it a key equivalent of alt/option. The symbol will appear in the field in the inspector, but not on the menu itself.

Now you can try it out. Make sure that both menu items are connected to actions, and run your program. Open your menu. You should see the first item you made. Now press and hold the ‘alt/option’ key. Your second menu item should ‘magically’ replace the first one!

We’re going to the Store, to the Store, to the Store (or not)

Today, Apple announced that they’re making an App Store for the Mac, similar to the App Store for the iPhone/iPad. This raises a number of questions and opportunities, not all of them pleasant.

I’m going to assume that you are familiar with the developers’ stories about the App Store, both good and bad. How much will a Mac App Store repeat these stories, and how much will change?

The iPhone App Store requires a rigorous analysis process of a program before it is released, both of the code and the content. Will the Mac App Store ban the use of private APIs? Will Mac apps be subject to the same opaque ‘community standards’ moral code? Will application be rejected on the basis that they ‘duplicate Apple application functionality’?

Assume that your application passes the requirements and is accepted by the store. Now you have to deal with pricing and payment. You’ll have to set up the byzantine tax and payment systems that Apple requires, and that iPhone developers complain about. You be guaranteed to be paying more taxes, since Apple collects and remits sales tax in every region that has them.

Hand over all your marketing and analysis to Apple. And you’d better hope it’s good. You won’t be able to track unique visitors, drive-bys, and demo downloads any more. In fact, you won’t have demo versions at all, if they follow the practices of the iPhone App Store.

Buyer beware is great for 99¢ apps, even $9.99 apps. But how do you convince someone to buy a $40 app, sight unseen?

How do you handle bad reviews? even a single anonymous bad review in the App Store could be fatal for a more expensive app.

Copy-protection. We all have schemes and serial numbers, some home-grown, some outsourced. They’re all crack-able, with different degrees of difficulty. Now think about Apple single-sourcing the copy protection. For one thing, it will be easier to crack on a Mac than on an iOS device, since the cracker has direct access to the binaries and a number of tools to help him. More frightening is the idea that if the Mac App Store protection is cracked, every application in the store is now free to download.

And what about upgrade revenue? That doesn’t exist in the current app store, and there are no signs of it coming. You sell one version, and then it’s free upgrades for life.

These are just a few of the issues I’ve come up with off the top of my head. I’m sure there are more, and I’m sure we’re all going to have to think seriously about them before committing to the Mac App Store.

I Want a Job

After getting laid off last year and getting depressed, and then looking around the job market for a bit, I’ve decided I want a new job.

Specifically, I want a job where:

Senior Management is actually involved in the company; other than trying to decide who to lay off. They actually have a vision for the company, and not a ‘mission statement’ full of business school buzzwords.

I want a job where:

Project Managers/Project Leaders actually have a plan. They know something about the project they are managing. They have design specs or requirements for the project; more than some notes scribbled on napkins or a database schema hand-drawn on a sheet of 11 x 17 chart paper.

They understand what a relational database is, what primary keys are for, and why users should never see them. They know that some of the people who work for them are experts, and should be listened to.

They don’t have ‘scrum’ meetings every morning where they all sit around a table for an hour or so. They actually know what ‘agile development’ means.

They spend more time with their staff working on the project than they do in meetings.

I want a job where:

My co-workers have a decent level of competence. They understand their jobs, so most of them understand basic software engineering principles. They know what terms like ‘version control’, ‘unit test’, and “resolution” mean. And they’re more interested in doing a good job than backstabbing their co-workers or brown-nosing management. They understand that they are at work, and don’t spend the whole day on the phone, or reading travel magazines, or looking at porn on the internet.

They don’t take naps at their desks in the middle of the day!

I want a job where:

The company takes quality seriously; they aren’t just interested in shipping a piece of crap to the customers. They have coding standards, conduct code reviews, have a testing process, employ competent QA staff, and conduct meaningful beta tests.

I want a job where:

Hell, at this point I could be wishing for unicorns.

I guess I need to find something else to do.

(P.S. All of the above is true, and happened at least once.)

NSScroller

I’m ba-ack! I really have been neglecting this block, and I’m going to try to post more often.

The subject of this post is the NSScroller class, since I recently needed to work with it and I found the documentation lacking and a bit out of date. Further, I couldn’t find much about the class on the web, and most of the comments involved sub-classing the control, which really isn’t a good idea. So here is what I’ve learned about NSScroller.

You almost never need to use NSScroller in your code, because NSScrollView will do everything you need. Also, consider using NSSlider instead.

So, you’ve thought about your UI design, and decided that a scroller really is the way to go. So, fire up Interface Builder, open your window, and drag a scroller instance from the palette to your window.

What’s that?

You can’t find the scroller objects in IB? That’s because they’re not there; you’ll have to create the scroller in code. It’s really not that hard. First, figure out where you want the scroller to live on the screen. You’ll need the x,y co-ordinates of the bottom left corner. Now, make a rect with those co-ordinates and the width and length of the scroller you want.

For my horizontal scroller, it looks like this


-(void)awakeFromNib
{
    NSRect winRect = [window frame];
    NSRect scrollFrame = NSMakeRect(20.0, 20.0, 
        winRect.size.width -40.0,[NSScroller scrollerWidth] );
    hScroller = [[NSScroller alloc] initWithFrame:scrollFrame];

Here, hScroller is a property so that you can get at it from other places in your code.

Now, there are a few setup steps that are necessary for the scroller to appear in the window.


    // Proportion is the amount of the scroller that
    // the knob takes up,
    // the width of the knob for a horizontal scroller,
    //  or the height for a vertical scroller.
    [hScroller setKnobProportion:0.05];
    // the scroller double value is the position of
    // the knob on the slider, with a range of
    // 0.0 to 1.0
    [hScroller setDoubleValue:0.5];
    [hScroller setEnabled:YES];
    [[window contentView] addSubview:hScroller];

The setEnabled message is necessary because the control defaults to disabled. I suspect this is for the scrollview implementation.

Now, if you run your program, you’ll see a scroller that you can interact with. The arrows work, and sliding the knob works. The next step is dealing with the interactions in code. You need to connect the scroller action to the controller.

So, back in the awakeFromNib method, add two more lines.

SEL mySelector = NSSelectorFromString(@"scrollAction:");
	[hScroller setAction:mySelector];

And that’s it; setup complete.

Now, to handle the messages sent by the scroller, you need to implement the scrollAction method. The trick seems to be to read the hitPart property to figure out which part on the scroller was clicked. Here is a sample handler:


- (IBAction)scrollAction:(id)sender
{
  switch ([hScroller hitPart]) {
  case NSScrollerNoPart:
    break;
  case NSScrollerDecrementPage:
    NSLog(@"decrementPage");
    break;
  case NSScrollerKnob:
    NSLog(@"scrollerKnob, value= %f",[hScroller doubleValue]);
    break;
  case NSScrollerIncrementPage:
    NSLog(@"incrementPage");
    break;
  case NSScrollerDecrementLine:
    NSLog(@"decrementLine");
    break;
  case NSScrollerIncrementLine:
    NSLog(@"incrementLine");
    break;
  case NSScrollerKnobSlot:
    NSLog(@"knobSlot, value= %f",[hScroller doubleValue]);
    break;
  default:
    break;
  }	
}

Now, when you get a page or line change you’ll need to adjust the doubleValue accordingly, to reposition the knob.

By experimenting with these messages you should be able to adapt the scroller to suit your needs.

One last thing: the top of the Apple documentation states that setFloatValue:knobProportion: is a commonly used method, but further on down you’ll learn that it is, in fact, deprecated. You should be using setDoubleValue: and setKnobProportion instead.

That’s it. If you have any questions, or anything to add, please let me know in the comments.

Bad Customer! No iPhone for You!

I decided to let the fuss die down a bit, so the week after the iPhone launch I phoned around until I found a Rogers outlet that had iPhones in stock. I drove down, waited a few minutes in line, and gave the salesperson my phone number.

He pulled up my existing Rogers account, looked at the screen, and said, “You’re not eligible.”

“Wha?”

“You got a new handset last September. You’re not eligible for a hardware upgrade yet.”

“I don’t want a hardware upgrade. I want to buy an iPhone, and put it on my existing plan. And pay more for the data plan.”

“Well, you can’t. I can’t sell it to you.”

“That’s crazy. You’re saying you won’t sell me the phone? Isn’t there some sort of penalty I can pay to get the hardware?”

“Nope. I can’t sell it to you. There’s nothing I can do.”

I went home, and called Rogers “Customer Service”. The first call ended abruptly as the agent put me on hold and I got disconnected. The second agent repeated what I heard in the store and said that the only thing I could do would be to cancel my existing contract, pay the $200 early termination fee, and start over from scratch. Oh, and lose my existing cell phone number in the process.

Now, I’ve been a Rogers customer for almost seven years. Any other business that had you as a paying customer for that long would be failing over themselves to keep your business. Anyone serious about customer retention would have offered existing customers first dibs on the iPhone. But not Rogers. They seem much more interested in signing new customers than keeping old ones.

I’ve had better treatment from credit card companies. Now that’s saying something.

Daring Fireball Sponsorship

I’ve joined with a number of other Mac Indie developers to sponsor the Daring Fireball blog for the next week.The press release is here. As part of the sponsorship, we’re each offering 20% off our respective products with the coupon code ‘DF2008′. If you don’t already have a license for Horizon now would be a good time to pick one up, and make sure to check out the other applications, too.

Off to See the Wizards

I’m heading down to the Apple World-Wide Developers Conference (WWDC) the second week of June. I plan on spending the days in Apple seminars and labs; learning as much as I can from the Apple engineers there. The objectives are to figure out the best way to build Horizon for the iPhone, and pick up enough about Mac development to take Horizon to the next level.

In the evenings I plan on hitting as many gatherings as possible; to shmooz and learn new and better ways to market the program. To that end I’ve started compiling the WWDC party list on Google Calendar. You can subscribe to it, or download the iCal version to your Mac or iPhone.

Here’s the link.

Please let me know of any other gatherings, and I’ll add them to the calendar.

Interview on MacNN

Last week, I was interviewed for the macnn podcast. You can find a link to the podcast here, it’s the 4th from the top. Victor Marks of macnn interviewed me about Horizon; how it works, how I developed it, and where it’s going. I hope this provides some insight into the program. Give it a listen and let me know what you think.