I checked out SBook5 last night. It’s Simson Garfinkel’s old NeXT app updated for OS X.
Though I’ve only spent an hour or so with it, I immediately found two very cool features.
The searching is fast and smart—and it updates with each keypress. Which is fun to watch, but it also means you may need to type only the first few letters of a word in order to find the record or records you want.
Perhaps even cooler is the brains behind the editor. It knows when you’re typing a phone number versus an address. It can tell the difference between a company name and a person name.
Besides being cool features, they’re inspiring to me as a developer. SBook5 is a reminder that computers can be pretty smart.
Huevos 1.0b2 released.
The source code can also be downloaded. (It’s an open source Cocoa app.)
Changes include improved preferences editing and remembering your last search engine and search string between runs of the app.
I just made the source code to the Frontier/Radio contextual menu plugin for OS X available via the open source BSD license. You can download it from the product page.
It’s definitely squirrel mating season in my back yard. I’m going to have to find out the gestation period of squirrels.
I’m also going to have to find out if boy squirrels can get pregnant. Holy cow, it’s nuts out there.
I read on a mailing list today that Apple’s planning to release a Web Services framework as part of the Core Foundation framework. It would be accessible to both Cocoa and Carbon apps, of course.
There’s a WWDC session named Client Web Services Frameworks that appears to confirm this.
From the description: “An explanation of important concepts and terminology is followed by an in-depth exploration of Apple’s WebServices.framework, a client-side framework for accessing Web Services from Mac OS X. Tools and techniques for writing Web Services glue and adding it to Cocoa, Carbon and AppleScript applications are demonstrated.”
I’m looking for a few beta testers for an app that will reach 1.0b1 sometime today or tomorrow. An OS X app, a Cocoa app, that’s designed to be fun. Not the world’s next killer app, to be sure—but I think (I hope) you’ll enjoy it.
If you’re interested and are willing to respect confidentiality, send me email (to brent at ranchero dot com) letting me know.
People sometimes ask me, they say, “Brent, why are you such a weird guy? What makes you such an odd duck?”
And I don’t know how to answer.
What can I point to? What’s the cause? Beats me.
Except that recently I’ve wondered if it might be my Dad’s fault.
I’ve been putting off doing an XML-RPC interface for my weblog software. The Blogger API wouldn’t work for me because each post has three elements: title, url, and text.
For some reason I had it in my head that the MetaWeblog API was designed to work with the Blogger API. I thought I’d have to support two APIs, and I wouldn’t be able to get, set, and edit posts with one call each.
I’m so pleased to discover that I was wrong. The MetaWeblog API does exactly what I need (a bit more, actually, but not too much more). My thanks go to Dave Winer and UserLand for a nice spec.
A Cocoa weblog editor should be a piece of cake. Most of the code would be just getting and setting Apple event parameters. (I’d use the Apple Event Manager to send the XML-RPC requests.) The rest is pretty much just layout, building a form in Interface Builder.
I won’t get around to it today or tomorrow or the next day. Maybe someone else will beat me to it, which would be just fine by me.
What with Bill Gates on the witness stand I figured it’s a good time to point to my bong hits with Bill Gates story from earlier this year. Just in case you missed it.
Maybe I’m the last person to discover it—there’s an outliner in AppleWorks. And it’s not bad. Imagine my surprise. Here’s a screen shot.
Sometimes you pet the kitty, and then he licks right where you pet him, and you’re sure he’s thinking: ugh, dirty monkey fingers.
So, to follow up on my earlier post about learning how to do icons—here’s my first icon that’s not completely embarrassing. It’s a toolbar icon that’s supposed to mean Open in Browser.
One has to have confidence when learning a new thing. I’ve never considered myself a skilled graphics artist. I can design simple websites with okay results—but note for instance that there are no graphics used in this site’s template.
As a desktop app developer I need to be able to make new icons. Not just app icons, but document icons and toolbar icons. Normally I would say: oh shit, I’m screwed, this is way too far out of my areas of expertise. I’m a text guy.
But I’ve decided to have confidence instead.
Theory: if you’ve reasonably intelligent and imaginative, you can learn to do just about anything pretty well as long as you have confidence.
So I found this cool set of tutorials at Iconfactory to get me started doing icons.
Who knows? Maybe I’ll end up not just okay at doing icons, maybe I’ll end up really damn good at icons. That would be a surprise for this text guy.
Less than three weeks into the season, the Rangers, who play in SafeCo field tonight, are already 8 1/2 games behind the first-place Mariners.
Do we still need to boo A-Rod? Or would pity be more appropriate?
Me, I like the idea of seeing 40,000 fans playing tiny, imaginary pity violins every time A-Rod steps to the plate.
Maybe it should be imaginary pity violin give-away night at SafeCo. Everybody who comes to the game gets a free, pocket-sized string instrument. (While supplies last.)
Or... on the other hand, maybe we should just boo him. 252 million dollars buys a lot of boos.
I don’t normally pay attention to what search terms I “own” on the various search engines—but I was amused to discover via my referers page that my site is #1 on Teoma for bong hits.
Since I work for myself, I can choose to be impolitic when I want to. So I’m going to say something I’m not supposed to say: I don’t like SOAP.
(Simple Object Access Protocol, that is. I like the other kind of soap.)
I like web services. And I’m glad when they’re implemented and adopted, even when they’re SOAP interfaces. Something is better than nothing. The trend is good.
But while XML-RPC is a thing of beauty, SOAP should have been named COAP—Convoluted Object Access Protocol.
It just plain offends me as a spec. People claim there are things SOAP can do that XML-RPC can’t do, but I remain unconvinced.
It’s a shame that for a spec to be adopted in the “enterprise” it requires a level of absurd obfuscation. It’s almost like a continuing employment clause for programmers. If you choose the psychotic spec, well, they can’t fire you, because they’ll need you too much.
It’s like IT managers choosing Windows because it’s harder to maintain, so they know their jobs won’t go away.
All that said, I’ll still use SOAP when necessary, of course.
Tonight I’m going to school for the first time in over ten years. I’m taking a continuing education class, elementary French, at the local community college.
I’m pretty excited about it. I’ve learned some French before, but my biggest problem is hearing it. Language is one of those things where to learn it well you need to learn with other people.
On a philosophic note: you’ve no doubt heard it said many times that the purpose of school is to teach you how to think, and that facts, the actual content of learning, are much less important.
I dispute that. Yes, school teaches you how to think—but the content of learning is hugely important.
Otherwise it’s like learning French without learning any vocabulary. You can’t communicate—you can’t even really think—without vocabulary.
This pleases me immensely—Studio Log published a collection of scripts for my Big Cat contextual menu plugin.
If anyone else publishes scripts for Big Cat—and I hope you do—please let me know about it. I’d like to make a page that links to all the places where you can get Big Cat scripts.
I’m working on a Cocoa class for reading RSS feeds. My intent is to make it open source (BSD license) so it’s available to other Cocoa developers. I chose the BSD license so people doing commercial apps can use it too.
Here’s what the API looks like. I’m seeking comments on its 1) Cocoa-ness and 2) usefulness.
initWithData (NSData) takes data and returns an RSS object.
initWithUrl (NSURL) takes a URL, gets it from the Web, then returns an RSS object. (It calls initWithData.)
lastReadDate returns an NSDate specifying when the RSS object was created (presumably when the data was last read).
version returns an NSString specifying the RSS version.
Here are the two interesting ones—the above are fairly non-controversial, I think.
headerItems returns an NSDictionary of all the stuff in the header: the title of the channel, webMaster, and so on.
itemsArray returns an NSArray of all the news items. Each item in the array is an NSDictionary containing the elements of the item: link, description, title, and so on.
I thought about normalizing headerItems and the items in itemsArray. What I mean is I thought about always having a ‘webMaster’ key in the headerItems dictionary even when that item didn’t appear in the RSS feed. (For instance.)
But I decided not to do any normalizing for these reasons:
1. Which spec would I normalize to? All of them? What about optional items? What about new specs that appear later on? In this case, normalization is what we doctors call a quagmire.
2. Normalization would remove potentially important information. You wouldn’t be able to tell the difference between an empty element and an element that wasn’t specified.
The downside is that anyone using an RSS object will have to check for existence. For instance, if you want to get the ‘link’ element of a news item, you can’t assume that the element exists. If it didn’t exist in the RSS feed, it won’t exist in the dictionary for that news item. But I think that’s okay.
I love learning, the actual experience of it, how you start with some new terminology and concepts, and some of it comes easily and other parts you just don’t get, but you keep at it, and you start to get things more and more, and soon you start to think in that subject, and further learning uncovers further depths.
There’s always a beauty to discover, however imperfectly realized.
I was wondering: how do you make XML-RPC calls from Cocoa apps?
It turns out that the Apple Event Manager supports XML-RPC. That’s so cool. Any developer already familiar with constructing Apple events will find doing XML-RPC calls a piece of cake.
And of course the example used in the above page is the canonical betty.userland.com example, a nice touch which warmed my heart.
As presence becomes more of a big thing, the old adage that “on the Internet no one knows you’re a dog” becomes less and less true.
They’ll not only know you’re a dog, but they’ll know when you go for walks, what kind of dog food you eat, who your dog-friends are, and so on.
There are two kinds of presence: real-time and not-real-time.
Not-real-time presence includes things like email and weblogs. This type of presence allows for an editable, leisurely, thoughtful projection of self.
Real-time presence is things like chat. You are really there, right now. An amazing technical and social achievement.
My issue with real-time presence is that it feels like surveillance. Voluntary and self-imposed (for now)—but how long before it’s more-or-less mandatory?
Even if it’s never abused by employers and governments and so on, even if it works just the way it’s supposed to work, it still means that you know what I’m doing.
I don’t want my computer to be your eyes upon me.
I want to use my computer to see out. And whatever I choose to reveal of myself I want to be able to think about first.
I don’t want you to know that I’m actually a dog.
When I walked outside today to get the mail I surprised a group of squirrels engaged in a menage à trois. No kidding.
I am now deeply confused about the animal kingdom.
I want to provide an RSS feed of my Macintosh news aggregator. Since it’s an aggregator it gets news from other RSS feeds. It is very important that those other sources get credited.
So what I did was use RSS 0.92, since it has a <source> element where I can put the name and URL of the source.
Here’s the feed itself.
Another option would have been to stuff information about the source into each description. That didn’t feel quite right to me. But then I suspect that not every RSS reader knows about the <source> element. Hmmmm.
What do you think?
P.S. This is another searchable RSS feed. Here for example are the search results for applescript. It seems to me that RSS is a natural format for search results, and I wonder why Google didn’t adopt it.
Yesterday I figured out how to display HTML in Cocoa. Given an NSTextView it’s just a half-dozen lines of code. Very easy.
The problem is that there are still some bugs. For instance, when I put my links in a table, the links stopped working. Nuts.
I love that first sip of coffee in the morning, that hot bite, the taste of potential energy.
I ordered a harmonica and a book on how to play it the other day. I love the dirty, tense sound of the flattened fifth. The secret knowledge of everything that’s nasty and fierce is suspended in that sound.
Theory: there are two types of cold wars on the Internet: cold wars where an intense PR battle is fought and cold cold wars where the entities do not acknowledge each other at all.
(A hot war on the Internet is where one or both entities do nasty stuff like denial-of-service attacks or selling a product at a loss in order to harm the competition.)
So one of my hobbies is cold cold war detection. Take any two entities that don’t acknowledge each other. Is there a cold cold war going on? If so, is it mutual or one-sided?
The trick is, any two entities may be quite reasonably indifferent to each other, and thus no war at all is going on. So it’s hard to be certain (unless you have inside information).
I’m interested in the intersection of the web and desktop apps. One app I’d like to see is a search engine for pages that I’ve visited. I often want to go back to something but can’t remember where it was but I can remember what it was about. A Google search would turn up too many hits. But if I could search just pages I’ve visited then I could find it.
The easy part is dumping the source of a page into MySQL or whatever and running a search page. The hard part is knowing when a new page has been loaded in the browser.
I can think of at least two ways to do the hard part, but I don’t like either way. (Proxy server or app that polls the browser.)
Years ago it worked with Netscape to tell it to please notify me when a new page has been loaded. I wonder if this still works, and which browsers it works with. This would be the best solution. Perhaps I’ll try it. (Or perhaps I’ll work on the dozen other things at the top of my to-do list.)
The GNUstep project is interesting, essentially a cross-platform Cocoa. I like the possibility of being able to port my Cocoa apps to Linux (or maybe even Windows).
This tutorial should seem familiar to Cocoa programmers.
I’ve been working on small-ish apps lately. Web apps and Cocoa apps. Here’s how I get started on a new app.
1. Define precisely what it does. I may or may not write it down—the goal is the feature list should be so small that I can keep it in my head without even trying. Also, the app should be describable in one sentence, even if that one sentence doesn’t cover all the features.
2. Sketch out the user interface. I use actual pen and paper. I may make several sketches until it’s right. A few days may pass between sketches as it gels in the back of my mind. The final sketch has labels and arrows so there’s no question of what does what.
3. Layout the interface in Interface Builder (if a desktop app) or with BBEdit and a web browser (if a web app). There may be iteration here, and I may have to go back to step 2.
4. Write a list of milestones. They should be simple, very fine-grained. The first milestone is usually just a do-nothing app that builds and displays the interface. The second milestone will do some small thing with hard-coded data. I’ll usually write down the first five or so milestones. I do not do a milestone list that takes me to the final product. Why not? Because I know to expect the unexpected. So what I do is add to the milestone list as I go along. I won’t know what milestone 10 is until I do milestone 5, for example.
I do fine-grained milestones because otherwise I get discouraged. I like crossing items off lists, and the more often I get to do that, the happier a developer I am.
I also use pen and paper for lists instead of a computer so I don’t have to switch out of my development environment to look at my list.
5. Now vee may perhaps to begin... In other words, get to milestone 1 and keep going.
I don’t necessarily advocate this process, by the way, I’m just describing how I personally get started on a new app. Note that I’m not working on a team or doing apps to someone else’s specs, both of which would require different processes.
Yesterday I added a bunch of feeds to the Mac News aggregator. Up to 15 feeds now.
I confess: I’m a news junkie.
In some ways Cocoa reminds me of Frontier in that there’s (usually) an easy way to do something and then lots of hard ways to do something.
The problem is that the easy way is not always obvious. The other problem is that I forget the rule that says, “If you’re standing on your head to do something, look for the easy way.”
So I was looking all over for how to set up an NSSplitView—a split window, like that used by most email apps. I couldn’t find anything. There’s no NSSplitView in Interface Builder’s widget pallete.
Then finally I noticed that I could do it via the “Make Subviews of” submenu of the Layout menu. It was so easy. And of course it just plain works.
Tip for Huevos users: you can search recent Macintosh news by adding a new search engine called Mac News with this URL:
I downloaded and tried out Chimera 0.2, the latest build of the Mozilla-based Web browser with a Cocoa UI and Unix back-end. They write: “The plan is to produce only a browser (no other apps!), and to keep the UI as simple and as clean as possible.”
So far so good. No one claims it’s ready for daily use yet, but if they continue on this path, there’s a good chance it will eventually be my browser of choice—probably alot of people’s browser of choice.
I’ve been working on an aesthetics of application design. I don’t claim that it’s complete or the only valid theory. Here are my thoughts in progress.
This is an age of software abundance. Sure, there may be apps that don’t exist that you wish you had—but there are far more apps available today than ever before.
This includes Web apps, a giant category which didn’t even exist a few years ago.
A few things follow from this observation:
1. People are asked to learn more user interfaces than ever before. Learning user interfaces is difficult and takes too much time.
2. If you the software developer don’t do something, some other software developer will. And that’s okay: that’s a good thing. It means the richness of the computer world doesn’t rely all on you: we can’t help but collaborate.
3. There is an abundance not just of software but of people using software, and each person has different needs, wants, and feature requests.
I conclude several things:
1. The simpler the user interface the better. A UI should be instantly learnable and usable, or as close to that as possible given the problem being solved.
In other words, the more apps there are, the more aggressively one should simpify your UIs. Anything else is just not fair to the people who use them.
2. Small apps that do one thing very well are better than monolithic apps that do lots of things unevenly.
Here’s what I mean. Say you have ten features you could implement. You could make a giant app that has all of those features. But any one person will only use three of those features. The problem is, for each person it’s a different three.
So an alternative approach is to do several smaller apps. Each one has a far simpler UI than the big app would have. Each one does one or a couple things very well.
Then users can pick and choose. They’ll choose which apps they want to use based on which features they want or need.
3. Apps should talk to each other.
This means using common, standard data formats, supporting Web services, Apple events, COM, pipes, and so on. Not that every app should support all these things: they should support whatever makes sense for that app.
It’s a key point, though. A computing universe of small apps would be just chaos and noise unless the apps can talk to each other and exchange data.
4. Scripting is important.
This goes to the above: a user should be able to do unexpected but important things with scripting. There’s a special place in the computing world for scripting systems: they’re the glue that ties everything together. Scripts are the energy that moves the bits.
5. Core apps should be extendable via plugins.
Apps such as BBEdit, Photoshop, Apache, and Radio UserLand—apps that implement core services of some kind—should be open platforms. There are plenty of cases where, instead of implementing another app, what a developer really wants to do is integrate his or her app into one of these platforms. That’s completely appropriate.
And note that BBEdit, Photoshop, Apache, and Radio all do have a plugin architecture, and this explains part of their popularity.
In both cases the user interface is as simple as I could make it. Huevos has one main window: choose a search engine from a popup menu, type in your search terms, then click a button to run the search. It would be hard not to understand it right off the bat.
I’ve had a number of people write me with feature requests, things I could add to Huevos. Several people have asked about adding a local find, something like a GUI wrapper for grep that would allow one to search your local hard drive.
And I think that’s a great idea—but if I do it, it will be another app. It won’t be Huevos. Because as soon as I add that feature to Huevos its UI would no longer be simple and instantly graspable.
My Macintosh news aggregator is also as simple as I could make it. I could have added a bunch of prefs so that members could customize their view by choosing how many items to display, what RSS feeds to show, and so on. I could have added a bunch of options to the search engine.
But I chose not to. Why? Because I want you to feel like you understand it, understand the entire thing, right away.
Because I respect you, I also want you to be able to decide right away if the app will meet your needs or not. If not, there are plenty of other aggregators, and probably one of those will work for you. I don’t want you to waste your time with a lengthy decision process regarding an app you understand only partly.
I’m still thinking about all this. Comments are, of course, welcome.
My weekend project was a Macintosh news aggregator. It shows the latest news; it’s also searchable.
Just for jazz, and because I think it’s cool, I put up a demo of the weblog editor I use for this site and for ranchero.com.
It doesn’t actually let you change anything in the database, but otherwise it works.
One is the Preview button. When you click it, it shows you a preview of the post you’re working on, formatted as it will appear on the home page. No round trip to the server required.
Another is the expanding/collapsing chevrons. I use those so I can glance at the titles to find the post I want to edit. Then I click the chevron to expand it.
One thing you can’t see: when I submit a new post, the CMS pings Weblogs.com, and I see the text returned from Weblogs.com right there in the page. It’s a friendly little confirmation that the ping worked. Of course, sometimes Weblogs.com reminds it would be a good idea to take a break...
In celebration of Spring I changed ranchero.com’s color scheme from a dull brown to a bright green. I had been going for a desert look, sort of a southwest thing, but it was kind of drab.
Here’s what I’m thinking about today: a Web-based bug tracking system that’s easy to use and easy to set up. The systems I’ve seen are too complicated. I want something simple that has just what’s needed to do the job and no more.
It may be that such a thing exists and I just don’t know about it, of course.
The ideal system (for me) is implemented with PHP and MySQL, since that’s what I have access to. It’s template-based. It’s membership architecture is open so that it can be extended to be used with an existing membership system on an existing site.
Most importantly its interface should be attractive and easy. The idea is that people who use my software should want to report bugs and make feature requests via the system. I figure most people just want to report bugs pretty much the same way they do in email—just type something and click a button to send it. A big intimidating form is not cool.
As an admin I have to want to use it. I don’t want to spend a bunch of time classifying bugs; I want it to maintain itself. For me it should be much like a discussion group: I just want to reply to bug reports.
However, there should be some minimum attributes. Which product, for instance, is important. Type of bug is important. I might like to be able to set priorities. (Maybe. That might be too much.)
It would have to be searchable, of course. And a desktop client (which communicates via XML-RPC, naturally) would be nice.
Here’s an OS X app that would be useful to me as a developer: a resource inspector. Given that I can’t run ResEdit (since removing Classic from my machines), I still sometimes have a need to look at resources. I don’t need to edit them necessarily, but I need to see them.
So this app would provide an outline view, or perhaps a browser view, of the resources in a file and show me their values. The top level would be resource types; the second level would be ids; the third level would be values.
I don’t think I’m going to write this app. (I already have plenty of other things to do.) But I’d sure be glad if someone wrote it.
I’m watching for the first butterfly of Spring. It’s a beautiful sunny day today, and I keep looking out the window, hoping to see something, even a cabbage white, go flitting by. Where are you, little friends?
I was going ape looking for a URL-encoding method in Cocoa. To my surprise it appears to lack one.
So this post is here for the search engines. Cocoa developers: you can call CFURLCreateStringByAddingPercentEscapes in the CoreFoundation framework to URL-encode a string. It takes (and returns) CFStringRefs, which are apparently interchangeable with NSStrings.
I always thought it was funny, the dog communications network. I’m walking along the sidewalk in my neighborhood and a dog starts barking at me. In sympathy another dog starts barking, which sets another dog to barking. Somebody in a house nearby gets a call from a friend in Chicago. Then dogs in Chicago start barking (since, with their great ears, they can hear the barking through the phone). The barking spreads all over the world in a flash. Then I cross the street to a block with no dogs. The barking all stops.
My fledgling writing career is starting to take shape. I just turned in an article I had been assigned, and I pitched an article idea to another magazine (an idea that wouldn’t have been appropriate for the first magazine).
This is fun! I can’t believe people get paid for this.
Of course I’m still learning about the business side of being a writer. I’ve got a little spreadsheet that shows the status of articles and ideas, for example.
Got tips? I’d love to hear from experienced folks on, well, pretty much everything, whether it’s about writing itself or the business side.
The point behind the OSAShell Scripting Component is to provide developers a basis for writing new OSA components for OS X.
It’s open source (BSD license).