inessential.com

Brent Simmons’s weblog.

Favicon 25 Mar 2019, 7:24 pm

Seattle Xcoders meeting this week is unofficial — no actual meeting. Just show up at the Cyclops (in the back, in the restaurant section) for food and/or drinks and conversation. Thursday (March 28) at 6:30 pm.

Lots of Apple news this week! But of course we talk about whatever. We could talk about Apple stuff if you want to. :)

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconNetNewsWire Sync Diary #1: It Starts with NSBezierPath 22 Mar 2019, 8:33 pm

In my Vesper Sync Diary I wrote about designing and writing both sides of a syncing system. I could make syncing work however I wanted it to work, and I had control of all of it.

Which is a great way to go. But it’s also terrible, because it means writing and running a server.

With NetNewsWire, I’m lucky in that there are existing systems — such as Feedbin, Feedly, Newsblur, and others — to use. I only have to write the client side.

I’m starting with Feedbin as the first syncing system. The first one is the hardest, of course — since there are a bunch of things the app needs for syncing that can be written once, but that do still need to be written.

How syncing will work

Users will add accounts to NetNewsWire — much as you do in Mail. Each account will have its own section in the sidebar (again, like Mail), which means you could have an On My Mac and a Feedbin account both active at the same time. (Just like you might have work and home email accounts active at the same time in Mail.)

You could even have multiple On My Mac and multiple Feedbin accounts. And, later, accounts with other systems.

When you make a change to the structure of your feeds and folders, the app will communicate immediately with the syncing system to perform the appropriate action. When you make a change to the metadata of an article (such as read/unread/starred status), the action will be coalesced and periodically (though fairly quickly) sent with other actions to the syncing system.

NSBezierPath

So I got started working on this, and almost immediately I found myself doing some custom drawing using NSBezierPath (which is a thing you use to fill and stroke lines, rectangles, circles, and other shapes).

Which sounds crazy, right? NetNewsWire has almost no custom drawing — in fact, before this, the only custom drawing was for the unread indicator (a circle).

And — bigger point — what does drawing have to do with syncing, anyway?

Well. There’s UI. Of course there’s UI — there’s always UI.

Users need to be able to add and edit their sync accounts, and I decided to do it the same way (surprise!) as in Mail — because this way the UI will be familiar to people who use Mail, which is surely a lot of Mac users.

I added a preferences pane called Accounts, and it uses the system-supplied icon for this exact case, and it has a thing like this on the left side…

Screenshot of the table and buttons on left side of the Account preferences

…or…

Screenshot, in dark mode, of the table and buttons on left side of the Account preferences

Looks much like Mail, right? (Not exactly the same, but it’s not important to make it exactly the same.)

The big space on top is a standard NSTableView, and the two buttons underneath are standard gradient buttons.

But what about that bordered gray thing to the right of the buttons? It has a background color and a border on top, right, and bottom edges — but not on the left edge, because that border belongs to the button.

There are a bunch of different ways I could have composed this whole thing, but in the end I just made that a custom view — AccountsControlsBackgroundView.swift — that draws its background and draws those three lines as a border.

(There’s probably an even simpler way using just one NSBezierPath instead of three. Or even a few NSBoxes used as lines. Whatever.)

My point isn’t that there’s anything interesting about this drawing — it’s that, when you go to work on a feature like syncing, the actual meat of the feature (communicating with sync servers) is often very small and easy.

User interface — design and implementation — tends to take up the bulk of the time, by far. By an amount that would surely surprise the heck out of people who don’t make apps.

In other words, it should never be surprising that work on a feature like syncing starts with an NSBezierPath.

Next step

What you see in the screenshots above is as far as I’ve gotten so far. The table view is empty; the buttons aren’t hooked up to anything.

The next step is to make that table view show a list of accounts, which, at the moment, is just the default On My Mac account. It should show the name and type of the account, along with an icon which represents the fact that it’s local-only and not synced.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 19 Mar 2019, 5:14 pm

On Twitter, Pádraig asks a great question, and probably every app developer should read the replies:

What are some of the reasons you would delete an app within a day of installing it?

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 17 Mar 2019, 4:47 pm

We don’t take him seriously because he’s crazy.

But crazy people do take him seriously.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 15 Mar 2019, 2:49 pm

The Nordic Museum in my neighborhood is now officially the National Nordic Museum. Very cool!

We also have a statue of Leif Erickson. And we hold a parade for Sytennde Mai every year.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 14 Mar 2019, 2:12 pm

Big story on RSS readers in the iOS App Store today:

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.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconSome More RSS-y Things 13 Mar 2019, 4:23 pm

I didn’t know that NewsBlur was open source — including the iOS app — and that David Sinclair works on it. Very cool.

* * *

The iDownloadBlog ends an article on Reeder 4 beta with this:

Is there anyone out there still using RSS?

Don’t tell me I’m the only one…

I get it. And I realize the person was kind of joking around.

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.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 12 Mar 2019, 6:39 pm

Reeder 4 beta for Mac is up!

I had been on the verge of writing about this. I’d noticed some people saying things to the effect of, “Oh, he must have stopped working on it. He’s been so quiet.”

This is one of those things that drives me nuts. When a developer says they’re working on something, and then they’re quiet, it’s because they’re busy working on it.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 12 Mar 2019, 4:50 pm

Back in the old days, when I would hear that someone was writing an RSS reader, I’d worry that it was more competition.

These days when I hear that same news, I get excited. Sure, I want lots of people to use NetNewsWire — but, way more than that, I want lots of people to use RSS readers.

The more the better, since no one app is going to be the right thing for everybody.

And here’s Rob Fahrni working on a river-of-news type RSS reader for Mac and iOS. Cool!

Writing an open source app, and not having to think about making money with it, is utterly thrilling. I love this.

Among other things, it means I get to be a cheerleader for other people’s work, which is totally fun for me. Makes me happy.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconFeed Discovery with Feed Compass 11 Mar 2019, 4:07 pm

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!

Big Internet Backup — discussed earlier. Give it a bunch of feeds, and it keeps everything forver. Searchable. Smart feeds. Etc.

Timeline/river-of-news reader - RSS presented as in a Twitter client. Reverse-chronological list. Super simple. Probably doesn’t even track read/unread (just position in timeline).

Microblog client as productivity app — multiple accounts, standard sidebar. Features like drafts. Scriptable. Searchable. Keeps items for a long time. Possibly even a detail pane that shows linked-to web pages. Connection to MarsEdit.

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.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconQuestions about Marzipan Apps on the Mac 7 Mar 2019, 4:54 pm

I’m thinking in advance about the things I’d like to know about Marzipan.

My questions, in no particular order:

  • Will we be able to ship Marzipan apps that run only on the Mac?
  • Will we be able to ship Marzipan Mac apps outside of the App Store?
  • Will there be a universal app format that includes iOS and Mac versions?
  • Will Marzipan Mac apps appear in the Mac App Store?
  • Will AppKit be deprecated?
  • If AppKit is not deprecated formally, will it get much in the way of new features?
  • Will apps have access to AppKit? Can they mix-and-match UIKit and AppKit?
  • Will apps be able to support AppleScript?
  • Will apps be able to send Apple events to other apps?
  • Will we be able to edit the main menu in Interface Builder?
  • Will apps support standard Mac customizable toolbars? If so, can these be edited in Interface Builder?
  • Will apps have resizable splitviews (without having to write this ourselves)?
  • Will apps support fullscreen with collapsible/slide-out-y sidebars?
  • Will apps support three-paned splitviews (a la Mail) without having to write the whole thing yourself?
  • Will document-based apps be able to open a separate window per document?
  • Will apps support additional windows? (In Apple News, choose File > Discover Channels & Topics… — what you really want is for that to come up in a separate window, I would think.)
  • Will apps support floating windows (such as for an inspector or a social media compose-message window)?
  • Will the Macintosh Human Interface Guidelines be updated to account for the differences in Marzipan apps?
  • Will table views support drag-and-drop to reorganize without doing the iOS modal thing with the grabbers in the cells?
  • Will there be some kind of way to use NSOutlineView (or equivalent)?
  • Will table views support standard Mac highlighting? And multiple selection?
  • Will sandboxing be required for Mac Marzipan apps?
  • Will the tab key work to move focus from view to view?
  • Will apps be able to use Mac-only frameworks such as SearchKit?
  • Is Apple working on a cross-platform, pure Swift app framework that would make Marzipan, UIKit, and AppKit obsolete?

We have hints at some of the answers — see Steven Troughton-Smith’s blog. (Subscribe to his feed.) He’s doing excellent work.

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.)

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconText-Editing Key Bindings and the Mac 6 Mar 2019, 3:16 pm

The system I wrote about yesterday for specifying key bindings in NetNewsWire is just a small version of the system built into the Cocoa Text System.

Most Mac users probably don’t know about this. I forget about it for years at a time. But you can actually customize text editing keyboard shortcuts globally by editing a plist.

(Link via Daniel Jalkut, sent privately.)

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconImplementing Single-Key Shortcuts in NetNewsWire 6 Mar 2019, 12:09 am

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.

Here’s an example of one of those files.

The keyDown implementation

SidebarOutlineView overrides keydown:

override func keyDown(with event: NSEvent) {
	if keyboardDelegate.keydown(event, in: self) {
		return
	}
	super.keyDown(with: event)
}

The keyboardDelegate gets the first shot at handling the key. If it doesn’t handle it, then normal processing continues.

SidebarKeyboardDelegate

There are several keyboard delegates, but let’s look at SidebarKeyboardDelegate, since these all work about the same.

In init it reads its keyboard shortcut definitions from a plist in the app bundle and creates a Set<KeyboardShortcut>. A KeyboardShortcut is a KeyboardKey (defined in same file) plus an action string.

A KeyboardKey describes the key, including its integer value and any combination of modifiers (shift, option, command, control).

In keyDown, SidebarKeyboardDelegate first gives MainWindowKeyboardHandler a chance to handle the key. MainWindowKeyboardHandler handles keys that are global across views.

If MainWindowKeyboardHandler doesn’t handle it, then it looks for a KeyboardShortcut that matches the pressed key.

let key = KeyboardKey(with: event)
guard let matchingShortcut = KeyboardShortcut.findMatchingShortcut(in: shortcuts, key: key) else {
	return false
}

If it finds a matching shortcut, then it makes the shortcut do the thing it’s supposed to do:

matchingShortcut.perform(with: view)

Performing the shortcut

Remember that a KeyboardShortcut has a KeyboardKey and an actionString. That string is pulled from the plist: it’s something like nextUnread: or openInBrowser:.

We turn this into a selector using NSSelectorFromString and store it in a local variable action.

(The Objective-C runtime has a particularly beautiful thing: messages are real things, and they exist separately from objects.)

The perform(with:) method looks like this:

public func perform(with view: NSView) {
	let action = NSSelectorFromString(actionString)
	NSApplication.shared.sendAction(action, to: nil, from: view)
}

Here’s Apple’s documentation on NSApplication.shared.sendAction.

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.

func sendAction(_ action: Selector, to target: Any?, from sender: Any?) -> Bool {
	var responder = NSApplication.shared.keyWindow?.firstResponder
	while responder != nil {
		if responder?.responds(to: action) ?? false {
			responder?.perform(action, with: sender)
			return true
		}
		responder = responder?.nextResponder
	}
	return false
}

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.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconXcoders Speaker Needed 5 Mar 2019, 2:56 pm

I you can make it to the Seattle Xcoders meeting March 14, and you might be interested in speaking, please get in touch! More details on xcoders.org.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconCool Stuff from The IconFactory 5 Mar 2019, 1:55 pm

Our good friends at The IconFactory are getting back to their roots by making free wallpapers and desktop icons — fun stuff, made for fun. Here’s how you can help support them with this.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconNetNewsWire Feedback Incoming 28 Feb 2019, 4:49 pm

I’ve been getting more NetNewsWire feedback now that I’ve called it actually usable now.

Feedback is always an education. (See the most recent issues for some of it.)

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

One of the unexpected things is Add way to see how many total unread items there are within the app.

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. :)

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 27 Feb 2019, 3:09 pm

Our community is mourning the loss of Tristan O’Tierney today.

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.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 26 Feb 2019, 4:43 pm

Joshua Blankenship misses 2004 and personal websites. (Via Colin Devroe.)

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconNetNewsWire 5.0d16: Actually Usable Now 26 Feb 2019, 1:12 am

The latest build of NetNewsWire adds searching, one of the last important things to do before shipping.

It still doesn’t have syncing yet. There are a few bugs to fix. It doesn’t have a new app icon yet.

But this is the first build where I’d call it usable. The core features of an RSS reader are there.

If you were holding off, waiting for a usable build, then you can stop holding off.

(But if you still want to hold off trying it until I add FeedBin syncing — or your preferred system — I totally understand.)

Reminder: it’s so basic it’s not even funny!

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconThe ODB Editor Suite: What I Remember 25 Feb 2019, 6:15 pm

The ODB Editor suite — which came up on the latest The Talk Show podcast — happens to be something I know about.

Here’s what I remember about how it happened… (Dave Winer or Rich Siegel may remember more, or better, and may correct me, and maybe not.)

I was working at UserLand, or maybe still doing contracting, or maybe I was still just an enthusiastic member of the community. I forget. But I was nearby when this happened.

Dave had written a website rendering framework for UserLand Frontier that generated static sites. This was the mid-to-late 1990s. The pages were stored in Frontier’s object database, which had its own text editor.

The problem was that some people wanted to use BBEdit instead of Frontier’s built-in text editor, because, well BBEdit was (and still is) awesome.

So we wanted to make it so you could be looking at text in Frontier, and then choose a menu command to open it in BBEdit for editing — and then have it automatically update in Frontier’s object database when you close it in BBEdit.

In other words, we wanted BBEdit to be an external editor for Frontier’s object database.

So Dave — working with Rich? Doug Baron? Jim Correia? I honestly don’t know who all worked on the details, though it wasn’t me — came up with the ODB Editor suite, which any text editor could support. (The BBEdit site has documentation.) BBEdit supported it, and other text editors added support too over the years.

The ODB part stands for Object Database.

Years later, for MarsEdit 1.0 (or some early version), I implemented the server side of the ODB Editor suite, so you could open something in MarsEdit in BBEdit, and have it save back to MarsEdit.

PS I use MarsEdit to this day. MarsEdit and BBEdit still support the ODB Editor Suite. Just to try it out, I’m writing this post in BBEdit, and it automatically updates the text in MarsEdit. It still works. :)

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 25 Feb 2019, 5:32 pm

There’s a measles outbreak in Washington State, where I live.

I try not to think about people not vaccinating their children. I nearly died as a result of having a terrible case of chickenpox during a blizzard. I live every day with damaged eyesight.

There was no chickenpox vaccine in those days. I sure wish there had been.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 21 Feb 2019, 7:26 pm

While working on show notes for an upcoming episode of The Omni Show, I found this classic blog post about Objective-C Memory Management & Garbage Collection.

I had completely forgotten about the finalize method.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 20 Feb 2019, 2:04 pm

In the latest episode of The Omni Show, I am the guest. How does this even work? Do I interview myself? What’s going on here?

PS I like being on podcasts, and I’d be happy to be on yours, to talk about Omni stuff or my own stuff or both. I could probably even convince Ken Case to be a guest on your show if you want to talk about Omni apps and developing for Mac and iOS in 2019.

(My email address is no secret, and every spammer everywhere already has it, so I’ll just post it here: it’s brent@ranchero.com.)

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconNetNewsWire Status: February 19, 2019 19 Feb 2019, 4:35 pm

There are three big things that remain before the first feature-complete build (which will be 5.0a1): searching, the app icon, and syncing with FeedBin.

Brad Ellis is working on the app icon, so that leaves searching and syncing (and a few miscellaneous bugs) for me.

I’ve been working on searching — I want to get that done next, and then do syncing as the last thing before hitting alpha 1.

How search is implemented

The UI for searching is pretty straightforward: you type into the search field, and then the timeline shows your search results. Click on an article to show it in the detail web view. Exactly as expected.

But there are two ways I can think of to implement this UI.

  1. When a search starts, do the search and show the results in the timeline. When the user ends searching, restore the previous timeline and detail view states.
  2. When a search starts, swap in a separate timeline and detail view, do the search, and then show the results in these swapped-in views. When the user ends searching, swap those views out, and swap back in the regular timeline and detail views.

Ideally the user can’t tell the difference between the two methods. But if you go with solution #1 — use the existing timeline and detail views — then you have the challenge of restoring state, including selection and scroll positions, when searching ends.

If you use solution #2 — swapping views in and out — then you don’t have that challenge. State is restored exactly as it was, because you saved the non-search views and swapped them back in.

(If you look at other apps — Mail, for example — it appears they use solution #1, and state restoration is not always instant. I want it to be instant.)

So, for the past week, I’ve been re-jiggering so that I can have multiple timeline and detail views and swap them in and out.

(This is not that different from how searching in iOS apps is supposed to work.)

And then, last night, as I finished the re-jiggering, I did the actual search-in-the-database implementation, which took about an hour.

This still leaves me to handle changes to the search field, so that the search is actually run at the right time, and so that searching ends properly. I expect that to take a few hours to get all right. (I’ve done this before, and it’s always slightly more complex than it seems.)

Why do I make this point?

If you’re not a programmer — or you’re new to programming, or haven’t written apps with a user interface — it’s easy to think that the actual under-the-hood implementation of a feature is what takes the most time.

It’s not. In the case of the search feature, I spent more time just thinking about how I want to do the UI than on the actual search-in-the-database implementation. And then there’s the UI work itself, which absolutely dwarfs the database work.

Another case: you might imagine that the bulk of the work in NetNewsWire was writing an RSS parser, for instance. But no. While that code is critical, obviously, it’s very, very small compared to the user interface.

And, similarly, the part of syncing that’s just making API calls and updating the database will be the easy part. The part that takes longest will be user interface. A factor of ten would not be surprising.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 13 Feb 2019, 8:14 pm

Jonathan T explains how to activate Apple ID 2fa when you have two accounts.

Short version: temp user on your Mac, SMS as backup, delete temp user, SMS keeps working.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconTwo-Factor Authentication and Developer Accounts 13 Feb 2019, 5:45 pm

I just got an email from Apple that two-factor authentication will be required for my Apple Developer account.

I have two accounts — one for personal use, one for development use — and so do lots of developers.

I don’t know how to make this work. None of my devices are ever signed in to my developer account. That account exists purely for building and distributing apps.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 13 Feb 2019, 2:21 pm

Brett Terpstra writes about blogging, ethics, and thin skin.

I’ve been reading Brett’s blog for years — I trust him, and he’s a good writer. I also use his app Marked pretty much every day.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 13 Feb 2019, 1:28 pm

Daniel Jalkut has bad news for Blogger users — Google is shutting down an images API.

Colin Devroe reminds us not to rely on mega-corporations keeping our beloved services alive. They won’t.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 12 Feb 2019, 5:14 pm

There’s still snow everywhere — but the sun just came out, and I heard some birdsong, and I looked outside and saw a couple robins.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 11 Feb 2019, 1:07 pm

Cliff Mass, Seattle’s favorite weather blogger, writes that the end of all this snow mess is in sight.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Favicon 8 Feb 2019, 1:39 pm

Cheri Baker writes about Spotify in Dear Podcasters…:

I fear we’ve seen this scenario before. A biggish company decides that they’ll aggregate an immense amount of creative work and monetize it. They’ll offer you tools to make “sharing” easy, and at first the terms of service will be reasonable. But once they’ve eaten a big enough chunk of content, they’ll lock the gates tighter, change the terms of service, and monetize the audience. By that point, customers would feel locked into Spotify, and podcasters would be afraid to leave.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

FaviconNetNewsWire Roadmap 2019 6 Feb 2019, 9:05 pm

Let’s look back at last year first.

2018: Evergreen to NetNewsWire

As 2018 started, the app was called Evergreen, which I still think is a pretty great name for an RSS reader. I’d been working on it for about four years, on weekends and at nights.

It was usable-by-me a year ago, and a few other people were using it, even though it was missing all kinds of important features.

And then, some time in the spring of 2018, I thought to contact the folks at Black Pixel about getting NetNewsWire back. Seemed like a total longshot. But why not try?

And they surprised me by being interested! In fact, they mentioned that they’d already been talking about it.

I was clear that I wanted just the name — not the code, not the then-current users, not the sync service. The app named Evergreen would be renamed as NetNewsWire, but would be, in every other way, the same app I was going to write. It would still be free and open source.

They agreed. And then, of course, discussions, mostly internal to Black Pixel, happened for a few months, because that’s how these things go — and we managed to make it official on August 31, 2018. (See NetNewsWire Comes Home.) Black Pixel gave it to me for free (we never haggled over price; that was their plan all along), and their generosity remains one of the things I’m most thankful for in my entire career.

Soon after that I renamed Evergreen to NetNewsWire — and memorialized the name Evergreen in the app’s bundle id: com.ranchero.NetNewsWire-Evergreen. (NetNewsWire will always be Evergreen.)

And so it turned out that I had been working on NetNewsWire 5.0 for four years already! I just didn’t know it for most of that time. :)

The rest of the year saw more work on the app, with code contributions from Maurice Parker, Olof Hellman, and Daniel Jalkut, with bug reports on GitHub, with the help of the folks on the NetNewsWire Slack group. (Which you can join too: just email me.)

That was 2018.

2019: Let’s Ship This Thing

At this writing we’re down to seven bugs in the 5.0 Alpha milestone. There are three main things: syncing with Feedbin, searching, and the app icon.

I want to ship 5.0 by WWDC, which is (most likely) the first full week of June. So here’s what I’m planning:

  • Finish those last bugs, and ship 5.0a1.
  • During the alpha period: write the Help book and document at least some of the code. Test, most importantly. Fix any bugs that get reported. Once there are no known defects, after a suitable period of testing, then ship 5.0b1.
  • During the beta period, continue testing. The code will be touched only with great reluctance. (Every beta is a shipping candidate.) Continue documenting the code.
  • Once there are no known defects, ship 5.0.

As you can see, the 5.0 Alpha milestone represents five years of work, and the alpha and beta periods ought to be relatively short, possibly just a couple weeks each.

But how quickly we get to alpha is mainly a function of how quickly I can get Feedbin syncing working and bug-free.

I think I can get it done by WWDC, but I could be wrong! No promises, of course. For NetNewsWire, app quality is everything, and hitting a date means very little.

Beyond 5.0: More Sync

There’s every chance that WWDC will bring changes and new technology from Apple that I’ll have to deal with. That’s expected — every app developer (hopefully) budgets for this. Assuming 5.0 is out before WWDC, then I can deal with this stuff in an update in the summer, in time for the next macOS.

There’s a huge list of features I could work on after that — there’s so much room for growth — but I think the big one has to be adding support for more syncing systems. I’m likely to do Feedly next, since it appears to the the most popular.

So my hope is to get Feedly support shipping by the end of 2019. And, if I do, then it will have been a very good year.

Blinklist Blogmarks del.icio.us Digg Ma.gnolia My Web 2.0 Newsvine Reddit Segnalo Simpy Spurl Wists Technorati

Page processed in 8.531 seconds.

Powered by SimplePie 1.0.1, Build 20070719221955. Run the SimplePie Compatibility Test. SimplePie is © 2004–2019, Ryan Parman and Geoffrey Sneddon, and licensed under the BSD License.