Really simple syndication — better known as RSS — is an enduringly useful technology that collects online articles from various sources in one convenient place.

The bummer about these articles is that the full thing can only be read in the iOS App Store. It would be nice if they actually appeared on the web, too.

The articles are often very well done and beautifully illustrated — and it would be to the benefit of Apple, and app developers, if these articles were findable and readable by people sitting in front of a computer.

But here’s the thing: tons of people use RSS readers. There’s no shame in it; you’re not the last person; there’s not going to be a last person.

This category of software is not going away, and no one needs to be meek about it. There are probably more RSS reader apps these days than ever before.

Other services for getting news and links exist too. But there are lots and lots of people who use RSS readers. Not still using them, as if they’re stuck in the mud. No: they are people who like them and see no reason to stop liking them! (Many of those people use other services too. Of course!)

* * *

Nick Heer writes about developments on the RSS front:

I think the hardest question for RSS readers is how it could gain broader interest outside of the more technically sophisticated user group.

I agree that that’s a hard question, but I’m also not sure if it’s the most important challenge. I’m not writing an RSS reader because I expect a mass market to use it. I think lots of people will, but nothing like the number of Mac users who use Twitter, Facebook, or even Apple News.

That said… we should be trying to bring the benefits of RSS readers to more people based on ethical grounds. Deliberately — or through inaction — reserving technology for a sophisticated group is Not a Good Thing.

The answer is probably a collection of answers, and the way to get there is step by step.

Maurice Parker, who’s contributed a lot to NetNewsWire, has started working on a directory app for feeds: Feed Compass.

It’s still at the proof-of-concept phase — very early days. The idea is that it can read OPML files from the web, show you a list of feeds, and show a preview of what’s in a feed when you select one. Most importantly, there’s a big Subscribe button so you can add the feed to your RSS reader.

The subscribe button should work with any Mac RSS reader that supports the feed protocol (which is probably all of them). It’s not just NetNewsWire-specific, in other words — it should work with Reeder, ReadKit, and others. (I haven’t tested this, though.)

* * *

This isn’t all of what needs to be done to make feed discovery easier and better. It’s a step, though, and it can be combined with other steps.

Some things I like about it:

It’s decentralized. It doesn’t rely on any one server, since servers may come and go.

It’s open source, which means you can contribute and/or fork. The code can’t go away.

It’s free, which means there’s no barrier to use.

It works (as I mentioned) with any Mac RSS reader, not any one in particular.

It could be ported to iOS.

It means we don’t need to include a feed directory built-in to NetNewsWire. (This helps keep NetNewsWire focused.)

* * *

Again, this is just the start of something. It’s not the one and only true answer to the problem of feed discovery — but it could be part of a collection of solutions that work together.

For more about discovery… When Maurice was doing research on the topic, he found this thread on Dave Winer’s GitHub enlightening, and I recommend reading it.

* * *

I had posted, to the NetNewsWire Slack group (email me for an invitation), a list of RSS app ideas. These are apps that could use NetNewsWire code to get a head start (though you wouldn’t have to).

The below is what I posted…

Here are some ideas for apps I’d love to write, that could use some NetNewsWire code, but that I’m too busy to write — but that would be cool if someone else wrote!

Feed creator — makes it easy to create feeds, including podcast and appcast feeds. (For instance: I do the appcast feed for NetNewsWire by hand, which is crazy. There should be an app for this.)

Feed debugger - given a feed, this app tells you about the issues. Is it a valid feed? Does it support conditional GET? Are attributes missing? Misspelled? Etc. This is especially important as it appears that feedvalidator.org may be down for the count.

Feed directory - reads in OPML from various sources on the web (such as Dave Verwer’s and Dave Winer’s collections) and creates a directory. When you select a feed, it downloads it and shows a preview of what you’d get. One-click subscribe to the default reader (whether it’s NetNewsWire or another app).

Though ideally these would be open source apps, they don’t have to be. (You can use NetNewsWire code in commercial apps, as long as you credit NetNewsWire in the about box or somewhere appropriate.)

I don’t claim that any of these are money-makers. Maybe some of them? Depends. I do think they’d all be very useful, and that you have a leg up since you can start with NetNewsWire code.

But it’s worth remembering that we don’t really know much yet, because even what we’ve learned so far may not reflect the actual shipping reality.

* * *

I care about the answers as a developer. Though I’m not going to rewrite NetNewsWire as a Marzipan app, I do have a bunch of other app ideas I’d like to do, and many of those should be iOS apps as well as Mac apps.

If Marzipan means I can get those apps made more easily and in less time — and that the Mac versions will be as good as an AppKit app, without compromises — then I’ll be happy to adopt it.

But that part is critical. It has to be as good a Mac app as the AppKit version that I would have written. Otherwise it’s not worth my time. Other people may make other calculations, and I respect that.

(Note to those who think of me as a Mac-only programmer: I’ve written several iOS apps, including Vesper, Glassboard, and early versions of NetNewsWire, AllThingsD, and Variety.)

NetNewsWire supports using single-key shortcuts for some commands: the k key marks all as read, for instance. The space bar scrolls the current article, or goes to the next unread if there’s nothing more to scroll.

There are a bunch of these, and they’re documented: see NetNewsWire Help menu > Keyboard Shortcuts.

These kinds of shortcuts are fairly rare in Mac apps, and rightly so — they’re best for apps where power users might need to process a bunch of stuff and move around quickly. That doesn’t describe every app (thank goodness!).

Since this isn’t really a standard AppKit thing, you might wonder how I implemented this in NetNewsWire.

Getting keyboard events

You have to override keyDown(with event: NSEvent) — so NetNewsWire has subclasses such as SidebarOutlineView in order to get keyboard events.

I could, if I wanted, just get the character from the event and do a switch statement with code like this:

case 'k':
markAllAsRead()

This gets ugly pretty quickly, and, importantly, I plan to make keyboard shortcuts customizable (at some point), so I chose a different path.

Property List Files

If they’re customizable, then the specifiers need to be stored in some data format. Property lists (plists) are a good choice, since they’re easy to read and edit in Xcode.

Now, I’m not making them customizable yet, but I figured it would be smart to use the same format and implementation for the default sets of shortcuts.

Inside the plists

There are a few plist files: one for global shortcuts, one for the sidebar, one for the timeline, etc. (I could have made just one file, but I didn’t. Doesn’t matter.)

Each file contains an array of shortcuts; each shortcut has a key and an action. The key is the actual key, such as k or ' — or a placeholder such as [rightarrow] where the actual key couldn’t be listed in the plist. (The app translates placeholders into their actual values.)

A shortcut may also have one or more modifiers, and those are represented as booleans: shiftModifier, for instance. This way we can differentiate between the space key and shift-space.

The action part is a string specifying which method to call for the given shortcut.

The short version of what it does: if to (the target) is nil, it starts with the first responder, then checks its nextResponder, then its nextResponder, and so on until it finds an object that responds to the specified selector (the action) — and then it asks that object to perform that method (or: it sends that message to the receiver). (It also checks the window’s delegate and some other things before giving up, when it gets that far.)

This means, for instance, that I don’t have to implement openInBrowser: in SidebarOutlineView. It could be implemented in its view controller, in MainWindowController, etc., as long as there is an implementation in the responder chain.

This way the implementation can be placed where it makes sense. I can even move openInBrowser: without needing to change the plist configuration.

And — this is important — it means that there might be (and there are, in NetNewsWire) multiple implementations of openInBrowser:. The sidebar has one which opens the home page of the selected feed. The timeline has a different one which opens the URL for the selected article.

The one that gets called is based on which one of these is the first responder, because that’s where the responder chain starts. (Which is another way of saying: the implementation that gets called is based on what thing has user focus.)

Both of these openInBrowser: commands are represented by the same KeyboardShortcut from the global keyboard shortcuts plist.

Not Magic

It may seem like NSApplication.shared.sendAction is doing something reserved for Apple that you couldn’t do, or couldn’t do easily.

But you could actually write this yourself. This simple version (which just checks nextResponder) has all the critical bits.

Obviously we don’t have the source to NSApplication.shared.sendAction — but, at least in concept, that’s all it’s doing. (Minus the part where it checks some things after exhausting nextResponder.)

Summary

In a Mac app, how does the Edit menu‘s Copy command know what to do? It walks the responder chain: the first to claim that it responds to the copy: message then performs the copy: method.

You don’t have just one copy: method somewhere that has to figure out the context (figure out what has focus) and then do the right thing. Instead, you may have multiple copy: methods.

(This is much less of a thing on iOS. But when you go to use Marzipan with your iOS apps, there’s a good chance you’re going to need to know about this.)

The Copy command (and others) use the same pattern I’m using here, in other words.

It’s also worth thinking about how nibs and storyboards actually get loaded by your app. All the wired-up actions are, at some level, just strings — so the frameworks (UIKit and AppKit) use NSSelectorFromString to turn these strings into real messages.

Having an idea of how all this works under-the-hood is useful knowledge: it means you understand your app better. It also means that when you’re faced with something like implementing a keyboard shortcuts system, you’ll have the right tools for the job.

(Of course this isn’t the right tool for every job.)

PS Try this!

In Xcode, set a symbolic breakpoint for NSSelectorFromString. Make the Action a sound. Check the box next to “Automatically continue after evaluating actions” — this way it won’t actually stop.

Now launch your app. Even if you don’t ever use this, your app sure does!

And, for bonus points, also set a similar breakpoint for NSClassFromString. Give it a different sound.

There are things I expect to see, and then do see. Things I expect to see, and then don’t see. And things I didn’t expect at all.

It’s a great reminder that everybody’s different, and people want different things. They want to use the app the way they want to use it.

The tricky part is deciding what to do, of course. When I was younger, and selling NetNewsWire, I was reluctant to add features and preferences — but I did it anyway. A lot. I wanted people to buy the app!

But it did mean that NetNewsWire became, in at least one person‘s words, a kind of “Swiss Army knife” of RSS readers. This made it difficult to move forward with new features that I thought would be cool and useful.

Now that I’m older, and I’m not trying to please everybody and make money, I’m even more reluctant. I want to keep the app as simple as possible — because I like simple apps, and because it means I have time to add other features that I’ve never done before, but that I always thought would be cool.

But, at the same time, I really do want it to be used by as many people as possible. So there’s a tension there which I find interesting. My position on it is just to go slowly — which I can’t really help anyway — and think hard about each issue.

One That I Did Not See Coming

There is a way, of course. There are two ways, even: the unread count appears in the Dock icon and beside the All Unread smart feed.

You’d think that would be enough — but it’s not. Consider that you might have the Dock hidden, and consider that you might have enough feeds and folders in the sidebar so that you can’t see the All Unread smart feed — it’s scrolled off.

Then what?

It could go in the toolbar — but some people run with the toolbar hidden. And, anyway, I never like status-y stuff in the toolbar. It could be a non-default toolbar thing — people could add it. But I’ve learned that lots of people don’t know you can customize toolbars.

How about a status bar at the bottom of the sidebar that can’t scroll off? Older versions of NetNewsWire had this.

Sure — but the trend these days, which I like very much, is to have a clean bottom edge to the window. No chrome. Look at Mail, Safari, Pages, and Numbers.

Well, okay — do that, but make it a View menu option, off by default, so we keep the clean edge.

Ugh. Now we’re going down the road of endless permutations of little things you can configure. That’s the road I want to avoid as much as possible. Do we really add that just because of the probably rare case where someone hides their Dock and the All Unread smart feed is scrolled off?

Another idea: that bottom-of-the-sidebar status view could appear only when the All Unread feed is scrolled off. But I really hate non-stable UI with weird little changes like that. It always seems too clever, and it makes me think the designer thinks they can paper over a design flaw by showing off.

Or there could be a non-scrolling indicator at the top of the sidebar. That ruins the nice line going along the top, though. But maybe the timeline needs a thing at the top for sorting, so maybe that line will go away anyway? And: wouldn’t this look weirdly redundant when the All Unread feed is not scrolled off?

So… what to do? I’m not actually asking for suggestions — though I’ll get some, because people tend to read things like this as problems-to-solve. (And I don’t mind suggestions. Not at all.) But what I actually intend here is just a look behind the development process at the point where people start giving feedback on an app.

Here’s what happens at this point: your design meets conditions you didn’t account for. They’re often rare cases, but they’re legitimate. And all the options seem pretty bad.

What will probably happen, in this case, is that I’ll punt on figuring it out till after 5.0 ships. I have no idea what I’ll end up doing. Which is part of the fun. :)

I met him before the iPhone days, I’m pretty sure. While we were never close, I was always happy to see him at WWDC and similar events, and I liked him tremendously. I had somehow missed that he had been struggling. I wish so much that he had not been.