Or try one of the following: 詹姆斯.com, adult swim, Afterdawn, Ajaxian, Andy Budd, Ask a Ninja, AtomEnabled.org, BBC News, BBC Arabic, BBC China, BBC Russia, Brent Simmons, Channel Frederator, CNN, Digg, Diggnation, Flickr, Google News, Google Video, Harvard Law, Hebrew Language, InfoWorld, iTunes, Japanese Language, Korean Language, mir.aculo.us, Movie Trailers, Newspond, Nick Bradbury, OK/Cancel, OS News, Phil Ringnalda, Photoshop Videocast, reddit, Romanian Language, Russian Language, Ryan Parman, Traditional Chinese Language, Technorati, Tim Bray, TUAW, TVgasm, UNEASYsilence, Web 2.0 Show, Windows Vista Blog, XKCD, Yahoo! News, You Tube, Zeldman
The Overdog Lovers 31 Jul 2020, 12:28 am
You run into those fellas in life and online who will always explain, for any situation, why the big company is right.
If asked, they will discuss their political and economic ideology. That ideology, they’ll explain, is about reality and logic — it isn’t some blanket defense of big companies. No way. It could just as easily defend small businesses and working people.
Except… every single time, without fail, they side with the big company. And then you realize that they’re the overdog lovers. They cling to the big wealthy power and hate the underdogs. It would be nice if they’d just say so.
I Got Teed Off and Went on a Long Rant About This Opinion Piece on the App Store 29 Jul 2020, 1:27 am
Ed Hardy, writes, in Congress, keep your mitts off the App Store. It’s fine. [Opinion]:
When Apple CEO Tim Cook takes questions from Congress on Wednesday, he’ll surely get an earful of software developers’ complaints about how the App Store operates. Chief among the criticisms will likely be the fact that Apple charges a percentage of revenue earned from in-app sales.
It’s not just a percentage of revenue from in-app purchases. It’s percentage of every paid upfront app, too. And the percentage is 30% for most cases.
There’s not a bit of justification for any of these highly publicized complaints. They come from companies that want to have their cake and eat it, too.
There’s plenty of justification. If you offer a Mac app outside of the Mac App Store, you can expect to pay about 5% to your payment processor. This option is not permitted for people writing iPhone and iPad apps.
It’s incredibly dismissive to accuse companies of wanting to “have their cake and eat it, too.” What companies want is to be able to pay their people and keep making the things they think are cool or good.
The next section of Hardy’s piece is called “The App Store does business like a grocery store.” But…
The App Store does not do business like a grocery store
…take a trip to your local grocery store. Suppose it’s a Kroger. You’ll find store brands — products made by Kroger — on the shelves next to products made by outside companies, like Procter & Gamble. I hope you’re not surprised that if you buy a Procter & Gamble product, Kroger takes a share of the revenue.
That’s exactly what Apple does with the App Store.
If I make and distribute toothpaste, I can offer the exact same product via Kroger, Safeway, and Albertson’s — and I could sell it from my own website and via Amazon.
That’s a lot of choices I have for selling my product.
But if I write an iOS app, I can sell it via the App Store and through no other method.
This is not at all how grocery stores work.
To be fair, it’s not just Spotify who’s complaining. The CEO of Epic Games (maker of Fortnite) whined about the App Store just last week. And the developers of premium email app Hey engaged in a very public spat with Apple in June, accusing Cupertino of acting like “gangsters.” But none of these companies’ criticisms hold up.
For whatever reason, developers are often accused of being whiny. Oh, those whiny developers who like to have their cake and eat it too. How dare they complain about Apple policies. Betcha I’m being a whiny developer right now.
No. Again: developers want to make great apps and be able to continue making great apps.
To demonstrate why, let’s continue with the grocery store analogy. Kroger built its store into a successful business. But suppose the companies who make the products sold in that store wanted to keep using it, without sharing any of the revenue with Kroger. That would be completely unfair. Kroger is paying upkeep on the store, but these other companies don’t want to contribute.
We’ve demonstrated that it’s not like a grocery store.
But let’s talk about fair share.
Apple — certainly among the wealthiest of companies in human history — is taking 30% of developers’ paychecks in order to show services growth. This is not about upkeep on the store: this is about profit for Apple. And not just profit but a specific category of profit.
And the rules aren’t remotely fair. Facebook — another fabulously wealthy company — certainly profits from its iPhone app. Does it share any of this with Apple? No. Instead, apps from smaller developers (because they are almost all smaller than Facebook) are subsidizing Facebook.
If there’s a fair share to be paid, the largest apps get away without paying it. Instead, companies like Omni subsidize Facebook. Fair?
* * *
The next section is called “Selfish developers want to use the iPhone ecosystem without paying their share.”
This is total bullshit and insulting. (Developers are always whiny and selfish, of course.)
This isn’t about paying a share into some commons run for all of our benefit. Apple isn’t just asking for us to help cover costs.
This is the only game in town for iPhone and iPad developers, and we have no choice but to subsidize apps like Facebook. We have no choice but to contribute to Apple’s services growth.
Of course, the analogy isn’t perfect, because it underplays Apple’s role. It didn’t just build a grocery store — it built the entire town. There would be nowhere for Spotify and the rest to sell their products if the iPhone never existed.
This is kind of the thing with platforms. There would be nowhere for Spotify to sell their iPhone app if there were no such things as iPhones. True.
The major reason these software developers have a business is because Apple makes iPhones that people carry with them everywhere. Without them, there’d be no Spotify. Fortnite would be a PC-only game.
I think the argument here is that, without Apple, the smart phone revolution wouldn’t have happened so quickly. That may be true! But it’s not argument in favor of Apple’s 30% cut.
These companies love to play on the idea that a 30% share of revenue is an egregious price to pay to be on the App Store. However, a recent study found that Apple’s percentage falls in line with other software stores (.pdf). And Procter & Gamble wouldn’t blink to hear that Kroger charges 30% extra for one of its products.
All of the various app stores are charging too much. They all point to Apple as precedent.
* * *
The next section is called “Consumers benefit hugely from the App Store.”
In some ways, sure. It’s also worth remembering that the more money Apple takes from developers, the fewer resources developers have. When developers have to cut costs, they stop updating apps, skimp on customer support, put off hiring a graphic designer, etc. They decide not to make apps at all that they might have made were it easier to be profitable.
Suppose the House Judiciary antitrust subcommittee — where Apple CEO Cook will answer questions Wednesday (as will the leaders of Facebook, Amazon and Google) — mistakenly thinks there is some justification for these developers’ complaints. Regulations that forced Apple to change the way the App Store worked would benefit a few big-name software companies, but they would hurt hundreds of millions of Apple users.
We have no way to know that — we don’t know what that regulation would look like or who it would benefit.
I do not want to see Congress regulate app stores. I want Apple to make better choices here — better for Apple, Apple customers, and developers.
But if Congress lowers the cut to 10%, or says that App Stores must allow for side-loading, it’s hard to see how customers would be hurt.
(That said — again, I’d really prefer not to see federal legislation. It shouldn’t be needed.)
True, Apple rules the App Store with an iron fist. While it sometimes acts in opaque and arbitrary ways, firmness is absolutely necessary in a world full of unethical developers who’d happily flood the App Store with crapware designed to steal user information. No one wants that.
Developers: whiny, selfish, and unethical.
Any time I hear about iron fists and the necessity of firmness, in any context, I get pretty nervous. But let’s set that aside.
App Store review is not filtering out apps that steal user information. No. This is done by sandboxing and other technical restrictions. Apps can’t steal user information. Apple — to its immense credit (it’s one of the things I love about Apple) — continues to lock this down.
Letting companies avoid this process would release a wave of malware on iPhone users everywhere. In a world where everyone’s phones are networked together, introducing another way for criminals to spread nefarious software is a horrible idea.
This is horribly, terribly untrue. Again: the App Store doesn’t prevent malware. Other technical limitations, built in to the platform, prevent malware. Apple does a great job with this and deserves all kinds of credit.
The second sentence in Hardy’s paragraph is just pure scare-mongering with no grain of truth.
* * *
The next section is called “Cupertino deserves its fair share.”
Cupertino deserves a cut of the action for the hard work it does policing the App Store. (And don’t forget about the enormous cost of operating and maintaining the servers that power this $519-billion-a-year economic engine, to say nothing of building the software tools developers use to create apps for iOS and macOS.)
Again: Apple isn’t asking us to cover costs plus a little something extra — no. Apple considers revenue growth in services to be of paramount importance, and this is one if its favorite ways of making that services money.
This isn’t about fairness at all. If it were, you’d think Facebook might pay some share.
Apple doesn’t “police” the App Store for the benefit of customers. Submissions are checked to be sure they adhere to Apple guidelines — in other words, reviewers make sure that apps are making money in approved ways and giving Apple its cut.
It’s also understandable that software developers want customers to pay them directly, rather than sending payments through Apple. And admittedly the company does make exceptions for certain services, like Amazon Prime Video, that bring customers to Apple’s ecosystem.
However, Cupertino’s general policy on payments means customers can feel safe shelling out for software and services within the Apple ecosystem. We know some shady firm won’t steal our credit card info. Even the best-intentioned companies get hacked, and I trust Apple’s network security far more than I do some random developer’s.
Again: this article mentions fairness a few times, and I hope it’s clear by now that the App Store isn’t exactly fair.
That thing about security and credit cards is more scare-mongering. If side-loading were allowed, most developers would use reputable systems like Square and Stripe and so on, where the developers never actually see credit card info at all.
(Developers are, by the way, whiny, selfish, unethical, and random.)
Maybe Apple’s 30% cut seems steep for digital products. But, as Ben Bajarin, head of consumer technologies at Creative Strategies, points out, the App Store seemed like a bargain to developers when it launched in 2008. At that time, developers typically surrendered 50% of the retail prices on software sold through physical stores. And small devs couldn’t even gain a toehold.
This is enormously untrue. I know because I was one of many small developers who were there.
We used Kagi as our payment processor at the time, and I think we paid around 5% for our storefront and payment processing and everything. Completely reasonable, and we were perfectly happy with it.
We were also a two-person shop — my wife and I — and you can’t get much smaller than that. Did we gain a toehold? Hell yes! We did great!
There were a lot of small companies operating that way. Hardly any of us were selling boxes through retail stores in the 2000s — we were already selling over the web by the mid ’90s.
Nobody saw this as a bargain. The developers I knew — small developers with nice toeholds! — were shocked and astonished, because we were used to paying 5-10%.
Perhaps Apple should shave a few percentage points off its take from App Store revenues to keep everyone (including Congress) happy. But third-party developers absolutely should pay a share of their revenue to support the iPhone ecosystem. Everyone benefits from it, including the companies that are whining. They just don’t want to admit it.
The traditional way of supporting a platform is to write good apps for that platform. That’s it. A platform with more and better apps will attract more people to that platform. (It’s not the only thing, but it’s a real thing.)
But Hardy — and Apple, apparently — has forgotten that simple truth.
And they haven’t realized that current App Store policies actually hurt the situation: we don’t have the quantity and quality of apps we should have. Which hurts that very ecosystem.
Apple’s Thirty Percent Cut 23 Jul 2020, 1:14 am
Developers will often tell you that Apple’s 30% cut isn’t the worst thing about the App Store, and that it’s actually far down the list.
True. They’re right.
But it’s worth remembering that money really does matter. Say you’re making $70K per year as a salary, and someone asks if you’d like a raise to $90K. You say yes! Because that extra $20K makes a real difference to you and your family.
To an app on the App Store it might mean being able to lower prices — or hire a designer or a couple junior developers. It might be the difference between abandoning an app and getting into a virtuous circle where the app thrives.
Quality costs money, and profitability is just simple arithmetic: anything that affects income — such as Apple’s cut — goes into that equation.
To put it in concrete terms: the difference between 30% and something reasonable like 10% would probably have meant some of my friends would still have their jobs at Omni, and Omni would have more resources to devote to making, testing, and supporting their apps.
But Apple, this immensely rich company, needs 30% of Omni’s and every single other developer’s paycheck?
I keep noticing that people say they “felt okay” about whatever they did. It was “just their grandkids” or “pretty much everyone was wearing masks” or “it seemed like they were being careful” or whatever.
The hospitals are full of people who felt fine about things.
Reminder: it’s a zillion times easier to hack Twitter and take over accounts of Apple, Bill Gates, Jeff Bezos, Joe Biden, and others than it would be to hack their separate websites.
Distributed systems are safer.
On “the blind leading the blind” 12 Jul 2020, 12:24 am
Local Seattle developer and good friend Olof Hellman finds the phrase “the blind leading the blind” problematic, and he writes:
Let your guide take you to Pike Place Market and taste the coffee and the piroshky and the crumpets and the nectarines and the chowder. Let your guide take you to the Olympic Sculpture Park, to hear the city and the train tracks and the ferry and the the wind curling around Alexander Calder’s Eagle, and taste the air from the Sound and feel the full force of the sunset. Let your guide take you to Sake Nomi where Johnnie will pour you a flight of Junmai Daiginjoshu and treat you like the Nomidachi regulars.
That right there is why we wish Olof would write every day.
Imagining SwiftData 11 Jul 2020, 9:29 pm
If SwiftUI and Combine are the new, Swifty V and C in MVC, where’s the M?
I keep thinking that Core Data, amazing as it’s been, is part of NeXT-world Apple, and we’re due for a Swift data model framework.
Instead of defining your model in a schema editor (a la Core Data), you’d use a Swift DSL — which would be nice because you wouldn’t have to keep the schema and your model code in sync. It would be just one thing.
It would use (or at least allow for) value types over reference types. It would use protocols instead of inheritance. It would play perfectly well with Combine.
It might not even use SQLite — I can imagine Apple creating a storage system more purpose-built. It might be built with syncing in mind first rather than as afterthought.
I have no inside knowledge. And maybe this is just wishful thinking. But it surely seems to me that something like the above should be coming — it would be weird if not, I think. Maybe next year?
Imagining an Open Source SwiftUI 11 Jul 2020, 7:00 pm
Swift is open source and is used in more places than just Mac and iOS apps — it’s now appearing in places like AWS Lambda, for instance.
But SwiftUI is not open source. At least not yet.
As a developer who uses SwiftUI, I’d sure like to see it made open source. I think there might be a good reason beyond just that, though — an open source SwiftUI could be made to work on other platforms.
Somebody would have to actually do that work, of course. But imagine that work has been done, and you can write SwiftUI code that runs on the web, Android, Windows, and Linux as well as on Apple devices.
Right now people are using web technologies and things like Electron to do cross-platform apps. And… it’s not great, and it’s hard to imagine Apple likes this situation. At all.
If SwiftUI makes it easier to make apps that work across Apple platforms only, that’s nice but not enough: the future will still belong to web wrappers like Electron.
The reason for that is simple. Apps cost a lot of money to make, and every additional platform costs yet more money.
The people who make the decisions on what to use aren’t generally the people who care about things like platform differences and performance. Those folks want to get the most bang for their buck, and so they’ll do what’s cheapest. Especially if you can’t prove, with data, the benefits of a native app over something like Electron (or other web wrapper).
(Bless those people. They are not Philistines as a rule — it’s just that they take their responsibilities seriously, as they should. They’re doing their job.)
But what if you could come to those people with an alternative — SwiftUI (and Combine) — and tell them that it will run everywhere, and that it’s at least as cheap as a web wrapper, and that it creates high-quality native apps?
That would be cool. I have no idea if that’s how people at Apple are thinking. But I hope they are.
Apple Privacy Changes 4 Jul 2020, 12:24 am
I was actually surprised at the changes Apple is making to stop tracking. It’s not enough to stop tracking on the web, and it’s not enough to stop tracking in iOS apps — which is happening probably way more than you think it is — so Apple did both.
While I know that Apple takes privacy seriously in a way other large tech companies don’t, I still didn’t expect them to go this far. I’m glad they did.
My pet theory is that this set of changes is the most important thing to come from WWDC this year. These privacy changes will, I think, have far more impact on the tech industry, on society, and on our lives, than SwiftUI or a new processor for Macs or anything like that. (As fun as those things are.)
It’s always going to be an arms race, I suppose — see this press release from Kochava:
Options exist to perform identity resolution using hashed-email-to-device linkages, device connections by household, and other first-party identifiers key in solving for identity resolution and attribution.
Further scarcity of the IDFA forces greater reliance on attribution by fingerprinting. Fingerprinting is a probabilistic method of attribution based on device IP & user agent that’s less precise than deterministic attribution based on the globally unique IDFA. Nonetheless, a high degree of accuracy is still maintainable with fingerprinting…
IDFA stands for “identifier for advertisers.” One of the changes Apple is making is that when an iOS app asks for the IDFA, the system will ask the user to consent to being tracked. When consent is not given, the IDFA will just be a string of zeros.
It’s self-evident that pretty much everyone will say no, which makes the IDFA useless. App makers will want to avoid even the shame of asking for consent.
Kochava is saying — and I’m betting they’re not the only company saying this — that they’ll find a way around the IDFApocalypse to identify users. They will probably succeed, too, at least to a certain degree.
However, Apple has shown that it has a mandate to fight, and the will, and it doesn’t mind dropping down some very large technical hammers to protect our privacy.
* * *
It’s important to note — before people get stigmatized unfairly — that most of the tracking and metrics collected by various websites and apps is done so with innocent motives. Marketers want to know which campaigns are more effective; they want to get the most bang for their buck. Product designers want to know which features are more popular; they want to know what’s working for people and what isn’t. Publishers want to know which pages people visit and how they got there. Engineers — like me — want to be warned of potential problems.
There’s nothing wrong with wanting those things! The people who want those things aren’t trying to snoop on people or anything — they’re using data to do their jobs better.
The problem is that the tech industry, in order to serve these needs, did what it always does: code up the thing, take the biggest bite it can, and hope to make enough money, and amass enough power, to be able to repel any future ethical distractions. So now we have mass surveillance.
But Apple recognizes that there’s still a need to know, for instance, which of your ad campaigns is doing best — and so there’s SKAdNetwork, which is a thing I don’t totally understand yet, but I get that it answers marketing questions in the aggregate (which is all marketers should want) and doesn’t violate privacy.
I like that Apple knows that it’s not enough to just shut down the bad actors — people who have questions to answer, but who have no interest in violating privacy, need solutions.
PS See the WWDC 2020 video Build trust through better privacy for way more about all this.
I Had Been Worried About the Mac 3 Jul 2020, 3:19 am
I spent the month or so before WWDC like you — suffering through a pandemic, outraged by violent racism, worried about democracy. Heartsick and appalled, mad and sad.
Nothing has changed since WWDC, either. Except for one thing. A small thing in comparison, but important to me — I had been very worried that Apple would, as part of the ARM transition, lock down macOS so that only Mac App Store apps would be permitted.
That didn’t happen. And Apple employees explained that it’s not going to happen — and, given that it didn’t happen this time, given that they had this chance, I believe them.
I understand adding security features to the Mac. But to take away our freedom to create whatever Mac apps we want, and distribute them without Apple’s, or anyone’s, seal of approval, would be to take the heart out of my career.
But that’s not what happened! I feel great about this. I’m going to stop worrying about the Mac.
The New Way of Making Apps
I’m excited about the new features in SwiftUI this year. This reminds me of the early 2000s when I switched from writing Mac Toolbox apps to Cocoa apps. It was a whole new way of writing apps, and it was so much better.
I jumped right on it, back then — and I feel no less enthusiastic for this new new thing than I did for Cocoa almost 20 years ago.
Apple has essentially said, I believe, that the way we’ve been making apps is all legacy. AppKit and UIKit both. SwiftUI is the future.
NetNewsWire and SwiftUI
We re-jiggered the NetNewsWire roadmap somewhat.
- Mac/iOS 5.0.x: bug fix releases
- Mac 5.1: Feedly, feature parity with iOS
- Mac/iOS 5.5: iCloud sync, other integrations and features
- Mac/iOS 6.0: SwiftUI, features tbd
The thing to call out here is NetNewsWire 6.0. We’re already at work building a SwiftUI app where Mac and iOS share as much UI code as possible.
The work is going very quickly: I’m amazed. If you want to follow along, or even help, take a look at the swiftui branch.
I’m super-psyched for this. If it means Mac and iOS can share most of their code, and we can add features more quickly (because SwiftUI makes for so much faster development), then we can ship more and better versions of NetNewsWire more often. I want that!
Reporting in After More Than a Month at Audible 3 Jul 2020, 12:20 am
I’ve been reluctant to write about how my new job is going — I don’t want to look like the guy who drank the kool-aid, and I certainly don’t want to be the guy who couldn’t read the room during our new multi-crisis normal.
But, maybe, some good news, even if for just one fortunate person, is okay to write about? I’m not even sure. But some of my friends have suggested I write it up, so I am.
* * *
Anyway. It’s going well! I love the job and the people and what we do.
Telling stories by way of human voice is among the most elemental and powerful of arts, and I believe that stories transform lives. My work at Audible is motivated by the same thing in me that makes me make NetNewsWire (an RSS reader), that made me create MarsEdit (a blog editor), that makes me write this blog.
Audible acts like a company with a mission. It seems like every company claims solidarity and support these days, and most of these claims are shallow and opportunistic. But Audible is committed to revitalizing Newark, NJ — from hiring locally, to Newark Working Kitchens, to Newark Venture Partners, and plenty more — and it’s helping, for real. This is not some new face for the current moment: it’s part of the company’s DNA and history.
And if you read the Audible blog, you’ll find that the company is dedicated to bringing us the stories that need telling and that urgently need to be heard.
It’s a good place that’s doing good, and I am proud to work there.
* * *
I’m on iOS. I’m senior enough not to be embedded in a scrum team, but I’m an individual contributor, not a manager. My job, broadly speaking, is to help the team increase velocity and quality. (My job isn’t strictly limited to iOS, but that’s where my focus is.)
My first month was spent meeting people (over video; via Amazon Chime) and learning things. The largest company I’ve ever worked at had about 100 people: Audible is much larger — 20 times larger? I’m totally just guessing — and that means I’ve had to learn about the ways of large companies. (Also remember that Amazon is part of this, usually in the background.)
I’m starting to be able to contribute a little — just recently I committed my first code. In any given month I might be writing a ton of code, or hardly any, or somewhere in between. While writing code is important, my job is more about things like architecture and best practices — it’s about finding ways to make the team better.
My background leading the NetNewsWire open source project is very relevant here. I learned, while running the NetNewsWire project, that people will rally to a higher standard if you can show them that it’s possible to reach it and then lead them there.
During my first month I felt like a detective from an Agatha Christie book, interviewing people and taking notes — What happened? How did we get here? What the heck is an ASIN? Those were the easy things to learn, and the hard lessons, where I learn how to take my experience and help lead us to that higher standard, are to come.
But that’s also the challenge! And the fun. It’s why I signed up.
* * *
I love this job every day except when I have to get up early due to time zone issues. Sheesh! (This happens just once or twice a month, seems like, so it’s not at all bad. It’s fine. But I Am Not a Morning Person.)
* * *
I haven’t noticed that the people I work with have a lot of public social media presence. (Maybe I just haven’t gotten clued-in yet?) But here’s Jeff Merola, the engineer I work most closely with. He’s smarter than I am, which is wonderful.
Accessibility and the Dynamic Nature of Objective-C 2 Jul 2020, 4:48 am
Doug Russell, who used to work on accessibility at Apple, writes:
some of the code that powers accessibility on apple platforms is just disgusting to look at and to work on.
most of the code that makes apple software accessible lives in what’s called an accessibility bundle. without diving into the minutia of the thing, bundles are a way to load something akin to a plugin into a cocoa app at runtime if an assistive technology is activated. it involves manipulating the app or framework class hierarchy and using objective-c dynamism to read app state and build up a usable accessibility hierarchy. insert a super class here, read an instance variable there, swizzle in a method and store the state for it in associated objects.
In other words — Objective-C and its runtime play a big role in making Apple’s great accessibility possible.
What happens when that’s not really a thing anymore?
Work at Universe 26 Jun 2020, 12:14 am
When I was looking for a job, I talked with the folks at Universe a few times. I love what they’re doing — an iOS app that helps people make websites — and I really enjoyed talking with the team. Such a great bunch.
The good news is: they’re still hiring. They have a bunch of jobs, even — iOS, Swift backend, database, product design, marketing, and support. Check ’em out!
PS Here are their key values.
Somewhat Live-ish and Around the Same Time as WWDC 24 Jun 2020, 5:33 pm
You’ll recall that James Dempsey does a benefit concert every year: Live Near WWDC.
Well, this year it’s not exactly live. But it’s still happening!
You may see me in the video. Wearing a Panama hat and dark shirt. Playing guitar and/or keyboards. But watch it anyway. 🐥🎸
WWDC 2020 and NetNewsWire 22 Jun 2020, 10:59 pm
I love seeing so much attention paid to the Mac this year!
I’ve applied for a Developer Transition Kit for NetNewsWire. My thinking: since NetNewsWire is open source, other developers can, and do, look at the code to help them write Mac apps. The sooner we have NetNewsWire updated, the sooner it’s available as an example for other developers.
The new Mac operating system, Big Sur, big number 11, Onze-y-baby, has some appearance and behavior changes which of course we’ll adopt. One of NetNewsWire’s values has always been to stick pretty close to Apple’s design for the platform. We do that because, well, we figure users of a given platform actually like the platform design, and that’s why they picked it. (It also tends to mean less work, which is a good thing.)
We’ll not be switching to Catalyst. It appears to be much-improved, but standards for a good Mac app are high, and I’m skeptical that Catalyst is all the way there yet.
Instead, our plan is to converge our UI code over time by using SwiftUI. This way we can go view-by-view. (It’s worth noting that we already do share some UI code: the article view is mostly shared, for instance, even without using SwiftUI or Catalyst.)
I’m looking forward to the rest of the week. I especially want to hear more about the new outline view in SwiftUI. 🐣🐥
The App Store Doesn’t Make Apps Safe 21 Jun 2020, 7:47 pm
Another misconception about the App Store is that it makes apps secure and safe. It doesn’t.
There are things that do make apps safe. No matter how an iOS app is distributed, it runs in a sandbox. An app requires permission from the user to do things like access the address book or microphone. This is just how iOS works: it has nothing to do with the App Store.
The App Store review process probably does run some kind of automated check on the app to make sure it’s not using private APIs and doesn’t contain some kind of malware. However, this could be run as part of a notarization process — this doesn’t have to be tied to the App Store. (Mac apps outside of the Mac App Store go through a notarization process.)
Otherwise, App Store review is looking for basic functionality and making sure the app follows the guidelines.
As far as checking that an app doesn’t crash on launch — thanks? I guess? As for following the guidelines: the guidelines are about protecting Apple’s interests and not about consumers.
I would like to say that the App Store filters out bad behavior, but I don’t think it does. We’ve all seen various scam apps, and we’ve seen otherwise well-behaved apps do things like abuse the push notifications system.
It probably catches some egregious scams that we never hear about. I’ll apply the benefit of the doubt. But it didn’t catch that, for instance, Path was uploading the user’s address book. The community outside Apple catches these things, and Apple changes how iOS works so that these things can’t happen without user permission.
And, at the same time, the App Store is a magnet for scam apps. Even in a world where side-loading is possible, scam apps would stick to the App Store because that’s their best shot at getting users to stumble across them.
People have asked if I’d want my grandmother to download iOS apps outside the App Store. The answer is yes. That was how she downloaded her Mac apps, after all. (She was an avid Mac user.)
I’d feel secure knowing that the apps, just by virtue of being iOS apps, are sandboxed and have to ask for permissions. (I’m also imagining a Mac-like notarization step, for additional security. I think this is reasonable.)
In other words: Apple has done a very good job with iOS app security and safety. The fact that we think this has something to do with the App Store is a trick, though.
(I’m not arguing for getting rid of the App Store, by the way. I’m arguing for allowing an alternative.)
The iOS App Store Brings Users Only Because It’s the Only Choice 20 Jun 2020, 9:45 pm
One might argue that developers should love the App Store because it brings the users.
AppleInsider writes about the App Store, Hey app, and David Heinemeier Hansson:
Like any other product or service, Hey has to persuade people that they have a problem it can solve, and that it’s worth paying for. You can’t persuade people of anything, though, if they don’t know about it. And then if you do persuade them, you can’t profit without a way to get your product into their hands.
His first argument against the App Store on Apple’s cut got Hansson and Hey a lot more notice than it might have. But it’s the App Store that gets his product to people. It’s the App Store that means if he persuades people it’s worth it, they can instantly have it on their iOS device.
This is a misconception that many people have — they think the App Store brings some kind of exceptional distribution and marketing that developers wouldn’t have on their own.
It’s just not true. It lacks even a grain of truth.
Setting up distribution of an app is easy and cheap. I do it for NetNewsWire for Mac with no additional costs beyond what I already pay to host this blog. This was true in 2005 as much as now — distribution is not some exceptional value the App Store provides.
And then there’s marketing. Sure, being featured used to mean something to revenue, but it hasn’t meant that much beyond just ego points in years. To be on the App Store is to be lost within an enormous sea of floating junk. No matter how well you do at your app description and screenshots — even if you get some kind of feature — your app will not be found by many people.
Build it (and upload it to the App Store) and they will not come.
Instead, you have to do marketing on your own, on the web and on social media, outside of the App Store. Just like always. The App Store brings nothing to the table.
So while it’s true to say that all of an iOS app’s users come via the App Store, it’s only true because there’s no other option.
If I could distribute my iOS app outside of the App Store, I would. I’d switch in a heartbeat. Even though it’s free and money isn’t my issue. It would make my work as an app maker easier.
I can’t reconcile in my mind the tension between Apple as the think different company, the pirates, the rebels, the company at the intersection of tech and liberal arts — and Apple the company that runs this legalistic, nitpicky, greedy, inhuman, happy-face Kafka App Store.
One Advantage of the App Store That’s Gone 20 Jun 2020, 6:30 pm
The best part of the App Store, years ago, from this developer’s point of view, was that it was easy to charge money for an app. No need to set up a system — just choose the price, and Apple takes care of everything. So easy!
But these days, in almost all cases, you’d be ill-advised to charge up front for your app. You need a trial version and in-app purchasing (IAP) and maybe a subscription.
Here’s the thing: this is a massive pain in the ass to implement, test, and support — Apple does not make it easy. It could, I think, make certain common patterns basically turn-key (like trial versions + IAP), but it hasn’t.
This means that, for many developers, the very best thing about the App Store — the thing that actually helped their business — is gone.
And it’s not just gone — it’s probably actually more difficult doing this stuff via the App Store than doing the same things (trial, IAP, subscription) using non-Apple systems such as Stripe.
(And, as a bonus, Stripe isn’t going to review your app’s business model and tell you no.)
Reading, Listening 6 Jun 2020, 10:00 pm
Not for the first time — but hopefully with more depth and breadth this time, and greater understanding — I’m reading and listening to Black authors and voices.
Anti-racism book recommendations are just a search away. Here’s one I found on the Chicago Public Library’s site.
Black Lives Matter.
Why NetNewsWire Is Fast 19 May 2020, 12:14 am
NetNewsWire is fast because performance is one of our core values. Being fast is part of the very definition of the app.
I suspect that it’s hard to do this any other way. If you take a month or two to speed things up, from time to time, your app will always be — at best — just kind of heading toward satisfactory, but never to arrive.
The best general advice I can give is just this: make sure performance is part of the foundation of your app. Make sure it‘s part of every decision every day.
Make sure, in other words, that performance isn’t just a topping — it’s the pizza.
Below are some of the specific reasons NetNewsWire is fast. Because NetNewsWire is — like many apps these days — basically a fancy database browser where data comes from the web, some of these will apply to other apps.
The below items are in no particular order.
Fast RSS and Atom Parsing
The most painful way to parse XML is with a SAX parser — but it’s also how you’ll get the best performance and use the least memory. So we use SAX in our RSParser framework.
On my 2012 iMac, parsing a local copy of some past instance of the Daring Fireball Atom feed — relatively large at 112K in size — happens in 0.009 seconds.
That’s fast, but we do another thing as well: run the parser in the background on a serial queue. Since parsing is a self-contained operation — we input some data and get back objects — there are no threading issues.
Conditional GET and Content Hashes
The parsers are fast — but we also do our best to skip parsing entirely when we can. There are two ways we do that.
We use conditional GET, which gives the server the chance to respond with a 304 Not Modified, and no content, when a feed hasn’t changed since the last time we asked for it. We skip parsing in this case, obviously.
We also create a hash of the raw feed content whenever we download a feed. If the hash matches the hash from the last time, then we know the content hasn’t been modified, and we skip parsing.
The parser isn’t the only code we run on a serial queue. When an operation can be made self-contained — when it can just do a thing and then call back to the main thread, without threading issues — we use a serial queue if there’s any chance it could noticeably block the main thread.
The key is, of course, making sure your operations are in fact self-contained. They shouldn’t trigger KVO or other kinds of notifications as they do their work.
(A simple example of a background thing, besides feed parsing, is creating thumbnails of feed icons.)
We Avoid the Single-Change-Plus-Notifications Trap
Here’s an example of a trap that’s easy to fall into. Say a user is marking an article as read. Calling
article.read = true triggers, via KVO or notifications or something, things like database updates, user interface updates, unread count updating, undo stack maintenance, etc.
Now say you’re marking all articles in the current timeline as read. You could call
article.read = true for each article — and, for each article, trigger a whole bunch of work. This can be very, very slow.
We have specific APIs for actions like this, and those APIs expect a collection of objects. The same API that marks a single article as read is used to mark 10,000 articles as read. This way the database is updated once, the unread counts are updated once, and we push just one action on the undo stack.
We also try to coalesce other kinds of work. For instance, during a refresh, the app could recalculate the unread count on every single change — but this could mean a ton of work.
So, instead, we coalesce these — we make it so that recalculating unread counts happens not more often than once every 0.25 seconds (for instance). This can make a huge difference.
For an app that is, again, just a fancy database browser, this is where the whole thing can be won or lost.
While Core Data is great, we use SQLite more directly, via FMDB, because this gives us the ability to treat our database as a database. We can optimize our schema, indexes, and queries in ways that are outside the scope of Core Data. (Remember that Core Data manages a graph of objects: it’s not a database.)
We use various tools — such as EXPLAIN QUERY PLAN — to make sure we’ve made fetching, counting, and updating fast and efficient.
We do our own caching. We run the database on a serial queue so we don’t block the main thread. We use structs instead of classes, as much as possible, for model objects. (Not sure that matters to performance: we just happen to like structs.)
To make searching fast, we use SQLite’s Full Text Search extension.
I could, and probably should, write more articles going into details here. The database work, more than anything else, is why NetNewsWire is fast.
Sets and Dictionaries
We often need to look up things — a feed, given its feedID, for instance — and so we use dictionaries frequently. This is quite common in Mac and iOS programming.
What I suspect is less common is use of sets. The set is our default collection type — we never want to check to see if an array contains something, and we never want to deal with duplicate objects. These can be performance-killers.
We use arrays when some API requires an array or when we need an ordered collection (usually for the UI).
Instead of guessing at what’s slow, we use the profiler in Instruments to find out exactly what’s slow.
The profiler is often surprising! Here’s one thing we found that we didn’t expect: hashing some of our objects was, at one point, pretty slow.
Because we use sets quite a lot, there’s a whole lot of hashing going on. We were using synthesized equality and hashability on some objects with lots of string properties — and, it turns out, hashing strings is pretty darn slow.
So, instead, we wrote our own hash function for these objects. In many cases we could hash just one string property — an article ID, for instance — instead of five or ten or more.
No Stack Views
My experience with stack views tells me that they’re excruciatingly slow. They’re just not allowed.
No Auto Layout in Table Cell Views
When people praise a timeline-based app like NetNewsWire, they often say something like “It scrolls like butter!” (I imagine butter as not actually scrolling well at all, but, yes, I get that butter is smooth.)
While we use Auto Layout plenty — it’s cool, and we like it — we don’t allow it inside table cell views. Instead, we write our own layout code.
This is not actually difficult. Maybe a little tedious, but laying out a table cell view is pretty easy, really.
I figure that optimized manual layout code is always going to be faster than a constraint solver, and that gives us an edge in smooth scrolling — and this is one of the places where an otherwise good app can fall on its face.
And: because that layout code doesn’t need a view (just an article object and a width), we can run it at any time. We use that same code to determine the height of rows without having to run an Auto Layout pass.
Caching String Sizes
Text measurement is slow — slow enough to make even manual layout too slow. In NetNewsWire we do some smart things with caching text measurement.
For example: if we know that a given string is 20pts tall when the available width is 100 and when the available width is 200, we can tell, without measuring, that it will be 20pts tall when the available width is 150.
There’s no silver bullet. Making an app fast means doing a bunch of different things — and it means paying attention to performance continuously. 🍕
Default Feeds Are Okay 18 May 2020, 10:15 pm
I just heard that the default feeds in NetNewsWire are okay as-is, and I don’t need to collect permissions for Apple.
Great! I’m so pleased.
Focusing 17 May 2020, 11:00 pm
Tomorrow’s the first day at my new job. Exciting!
Starting a new job has led me to look at my entire list of responsibilities — which is too long — and figure out what I need to drop so that I can pay enough attention to the projects that need it most.
My most important projects (outside of my job) are NetNewsWire and this blog. This blog, because, well, blogging is part of how I breathe. And NetNewsWire because I love the app — and it’s a real thing in the world now, with users, a team of developers, and great features coming up.
I wanted to do another half-dozen or so apps alongside NetNewsWire, starting with Rainier, but I’m dropping development on those so I can concentrate entirely on NetNewsWire. This is personally disappointing, but it’s honest: I just don’t have time for Rainier and these other apps. Work on these would take away from NetNewsWire, and that would be wrong.
Another move I’m making: Manton Reece has agreed to take over the repo and website for JSON Feed. I’ve been the bottleneck here with a 1.1 version, and I shouldn’t be. Manton will take care of this way better than I’ve been able to. (I hope to get everything transferred over to Manton in the next few weeks.)
My New Job 12 May 2020, 5:49 pm
As of this morning the ink is all dry, and I can happily report that my new job is at Audible. I’ll be an architect on the mobile team.
I’m very excited for this job! It’s perfect for me in so many ways — not least that it’s about books.
My plan is for this to be my last job — I plan to work at Audible until I retire. I start Monday. 🐣🐥🕶
NetNewsWire 5.0.1 for iOS Released 12 May 2020, 5:37 pm
While I’ve been job-hunting, the mighty NetNewsWire team has kept rolling — and today we published the first update to the iOS app.
This update fixes bugs, makes the app faster, and adds polish. Read the (rather lengthy) change notes for the full scoop.
We did add one new feature: on the settings screen you can choose which color palette to use: go with the current system setting or specify light or dark.
If you’re already running NetNewsWire, it should update in the normal way. If you haven’t tried it yet, go get it — for free — on the App Store.
My Mac App Store Debate 12 May 2020, 4:53 pm
The question of publishing NetNewsWire on the Mac App Store won’t be decided until the minute that it’s actually published there.
If it ever is, that is. I go back and forth on it.
Here’s the thing to remember: our goal is to get as many people using RSS readers as possible. Period. Keep this goal in mind.
Publishing on the Mac App Store would mean that some people would see the app who might never have seen it otherwise.
There are also people who, due to personal or workplace policy, download apps only from the Mac App Store.
Publishing on the Mac App Store seems like a no-brainer, then. We’d get more people using RSS readers — we’d further our goal.
But it’s not so simple.
As with everything else, there are trade-offs. There are costs and benefits.
The benefit is reaching more people. There are several costs.
Some are right up front: we’d have to sandbox the app and test it. We’d have to do a set of screenshots for the Mac App Store; we’d have to write the description text for the page.
But I don’t mind one-time costs that much when there’s a solid benefit.
There are ongoing costs, though: we’d have two configurations of the Mac app, one for the Mac App Store and one for direct download, and we’d have continue to maintain and test both. This is kind of a pain, but not terrible.
The Real Cost
There’s a cost that’s worse than the technical and testing costs: I would have to deal personally with the stress and uncertainty of a second App Store. The NetNewsWire team is amazing and does a ton of great work — but the team can’t do this part. It’s on me.
The issue with the default feeds reminds me that, at any time, even for a small bug-fix update, App Store review may decide that an app can’t be published as-is for some reason.
You‘d be right to think that, with an issue like this, it would come up the same on both App Stores — solve it in one place and you’ve solved it in both. It’s not like I’d have double the issues.
But sometimes the issue actually is platform-specific. For example: NetNewsWire Lite 4.0 for Mac was held up by Mac App Store review for three weeks due to a bug in WebKit. (Yes, this was nine years ago.)
This is supposed to be fun. It’s work that I love doing for a great cause. And I just keep thinking that dealing with the iOS App Store is enough to ask of me, and there’s no requirement that I go through this with the Mac App Store too. The personal cost is just too high.
Other Ways to Achieve Our Goal
We can achieve our goal in other ways: ship Feedly syncing on the Mac, ship iCloud syncing on both apps, continue making the app more appealing to more people. Do more marketing.
In other words, publishing on the Mac App Store is not the only lever we have, and I’m leaning toward just not doing it. At least not this year.
We’ve got other, better things to do — and I’ll enjoy those things a hell of a lot more, and I think you will too.
On Talking with the Duet Folks 12 May 2020, 2:19 am
One of the teams I talked to during my job hunt — and that didn’t put me through a scary tech interview :) — was the folks at Duet.
They make an app where you can use an iPad as a second screen for your Mac. They also support Android and Windows. (You should check out their apps.)
I thoroughly enjoyed talking with the team, and I believe I would have been very happy working there.
They’re looking for a Mac developer. Maybe you? Get in touch via their contact page.
More on the Default Feeds Issue 12 May 2020, 1:08 am
Here’s the latest on the story from yesterday.
NetNewsWire 5.0.1 for iOS was approved for the App Store this morning, and I assumed that was the end of it. I figured this whole thing was just an error.
But later today I heard from Apple that, while this latest version has been approved, the app is now under further review for this issue.
This isn’t quite over yet — but at least we could ship 5.0.1, so that’s cool, and I’m glad.
The issue really is about the default feeds. They’re added by default on the first run of the app.
Apple suggested some options — things I could do if, after further review, they decide that I need to bring the app into legal compliance:
- Provide documentation (to Apple) expressing permission to use those feeds as defaults
- Have the user, on first run, pick from a list of these feeds
- For these feeds, show only a title, and then link out to Safari
For now I’m not doing any of those things, since Apple’s review is ongoing. I’ll wait for the review to complete.
If the review completes and I do need to do something, I’ll take the first option: I’ll get the necessary documentation.
(Yes, I could change the UX instead. But I don’t want to — the app works the way I think is best. You could debate whether I’m right or wrong on that point, but there’s no debating that this is the UX I want.)
I’m Not Actually Against Getting Permission
As I wrote on the NetNewsWire FAQ about the default feeds:
We change the feeds from time to time. We don’t have any arrangements with the feed owners, though we usually ask permission — unless it’s something like Daring Fireball or Six Colors where it would obviously be no problem.
The authors of Daring Fireball, Six Colors, and a few other sites are friends, and I don’t need to bug them to ask permission. There are other default feeds where I know the people less well (or not at all), and I have asked permission from people — not because I was worried legally but because it seemed like basic courtesy. I don’t think anyone’s ever said no, but I did want to give them the chance.
But can I find all these conversations, and can I turn those conversations over to Apple without asking the other parties?
I don’t think so. So this would mean going through and getting explicit permission from a dozen-ish different people and turning copies over to Apple.
Which is fine. I can do that if Apple decides they need that documentation. It’s not onerous.
What Still Rubs Me the Wrong Way
I’m trying to figure out what bothers me. I think there are two things.
One is just that the App Store has always seemed rather arbitrary. The guidelines don’t even have to change for unseen policies to change, and it’s impossible to know in advance if a thing you’re doing will be okay and stay okay. (Recall that NetNewsWire has been doing the same thing with default feeds for 18 years.)
This gets really tiring, because every time we submit an app — even just a bug-fix release, like 5.0.1 is — I have to deal with the anxiety as I wonder what’s going to happen this time.
The other issue is a little harder to explain, but it goes like this:
If a site provides a public feed, it’s reasonable to assume that RSS readers might include that feed in some kind of discovery mechanism — they might even include it as a default. This is the public, open web, after all.
Now, if NetNewsWire were presenting itself as the official app version of Daring Fireball, for instance, then that would be dishonest. But it’s not, and that’s quite clear.
To nevertheless require documentation here is for Apple to use overly-fussy legal concerns in order to infantilize an app developer who can, and does, and rather would, take care of these things himself.
In other words: lay off, I want to say. I’m an adult with good judgment and I’ve already dealt with this issue, and it’s mine to deal with.
Heads-Up to RSS Reader Authors 11 May 2020, 12:45 am
Update the next morning (May 11): NetNewsWire 5.0.1 for iOS has been approved for the App Store — which happened before I had the chance to provide documentation. I will assume that the policy enforcement change described below was just an error.
NetNewsWire 5.0.1 for iOS is delayed due to an apparently new, or newly-enforced, issue: if an RSS reader includes default feeds, Apple will ask for documentation that says you have permission to include those default feeds.
The first RSS app that got tagged with this, that I know of, was NewsWave. We submitted NetNewsWire 5.0.1 for iOS for review a couple days ago and had the same issue.
Specifically, it’s in violation of legal guideline 5.2.2:
I need this for the default feeds. A couple of those are mine, and so I need about a dozen documents to cover all the default feeds.
I could complain about this — the default feeds have never been an issue in NetNewsWire’s 18 years of life — but I’m done and can’t even right now. I’ll do what I have to do.
I do have a follow-up question, though: could an RSS reader contain some kind of directory of feeds, in order to help people with feed discovery?
NetNewsWire of Old had this, and some kind of modern version would be a good idea. We’ve been talking about it. But if we have to get documented permission for every single feed in the directory, we probably wouldn’t do it.
PS If you write an RSS reader for Mac or iOS, and want to ask me any questions about this, feel free to email me.
The Ideal iPhone App First-Run Experience Is None At All 9 May 2020, 6:06 pm
Consider the person who finds your app on the iOS App Store. They decide they want your app: they tap the get or purchase button.
The app downloads — hopefully quickly; hopefully you‘ve made it small, because you’ve pictured this moment and you care about even this aspect of the user experience — and then the user taps the Open button.
They’ve already waited to see the app. They’re excited to see what it’s like and get started using it!
And, now that it’s here, you can put a bunch of obstacles in their way — which will cause you to lose some of these people — or you can satisfy their interest and curiosity right away by getting them into the app.
* * *
Here’s me: when I download an app with a first-run tutorial, I try to find a way to short-circuit it and get to the actual app. If I can’t, I just race through it, knowing I wouldn’t have remembered any of it anyway.
Either I can figure out the app later or I can’t.
Similarly, if an app has first-run setup to do, I try to avoid it. If it has first-run setup and a tutorial, I’ll just give up unless I know for absolute sure that I want this app.
* * *
Isn’t there some quote, maybe even from Steve Jobs, about apps early in the day of the App Store, that went something like this? “iPhone apps should be so easy to use that they don’t need Help.”
I’ve always thought to myself, since then, that if I see a first-run tutorial, they blew it. Apps should be designed so that you can figure out the basics quickly, and then find, through progressive disclosure, more advanced features.
It seems to me that the best first-run experience is to get people into the app as quickly as possible, because that’s where they want to be.
They’ve already waited long enough — finding the app, downloading it — and now you want to delay the joy even longer, and thereby tarnish or even risk it? Don’t do it!
Remember that people are busy, often distracted, and there are zillions of other apps. Your app is not the world. The person is the world.
* * *
Remember that every single thing in your app sends a message. A first-run tutorial sends the message that your app has a steep learning curve. Definitely a turn-off.
It provokes anxiety in the user immediately, in two related ways: 1) “Will I ever be able to learn this apparently hard-to-use app?” and 2) “Will I remember any of this tutorial at all? Do I need to get out pen and paper and take notes?”
And that’s the first impression. Your app makes the user anxious.
What Happened When I Looked at Two Mac Apps Today 7 May 2020, 10:40 pm
I’m not going to name names here. Don’t worry. :)
I’m in the market for a Mac app for _____. It’s a not-uncommon need, and so I figured I’d have some good choices.
I’d also like an iOS app that syncs with that Mac app — but the Mac app is the more important of the two, because I sit in front of a Mac all day. (To me. Some people are iOS-first, which is totally cool.)
I downloaded and tried a couple apps. One required an account just to try the app, which pissed me off, but I did it anyway.
Window Resizing Test
The first thing I tried, with each app, was to resize the window. This is a good test because I get frustrated with sluggish apps: window resizing is a decent way to get some idea of how the app performs.
I know I’m not playing fair — I’m on a 2013 MacBook Air — but the app I write is fast on this machine, and other apps should be too.
Both apps were sluggish with window resizing. They were bad enough that I could have just stopped right there.
But it was actually worse than that.
With one of the apps, the upper position of the window could actually change during window resizing. It could even go offscreen. I don’t even know how that bug is possible.
The other app was almost as bad: the upper position of the window would sometimes jump down around 20 pixels then back up, real fast. It made the window seem to flicker. Nasty.
The basics of window resizing behavior should be impossible to mess up — AppKit should be handling this. If it’s messed up, then something in the app is fighting the frameworks. That’s a bad sign for the quality of the rest of the app.
I picked an action that would be 1) super-common and 2) something that every user should expect to be undo-able.
In one app, I did the thing and then chose Undo. It didn’t do anything that I could see — the Undo command was available, but had no visible effect. I did Undo again. No visible change. God knows what was happening.
In the other app, Undo just wasn’t available. This is actually better than a faulty Undo — but, still, it’s not good.
That Was Pretty Much It
I poked around a little more, enough to find some additional bugs, and then I trashed both apps. I deleted the account I had had to create for the one app.
By not paying attention to the basics of a good Mac app, each of these apps lost a potential customer who’s 1) happy to financially support app development, and 2) who has a blog that a bunch of people in our community read, where he likes to praise things that are good.
Maybe that’s not worth it? But doing a not-good Mac app is somehow worth it? I don’t understand.