inessential by Brent Simmons

Mysterious SwiftUI Crash

A friend just released a new version of their app — and it has a new crash not seen during development.

This new version of the app has a bunch of new SwiftUI code, and this crash is definitely in SwiftUI — but it’s apparently in SwiftUI itself.

Anyone else seen this? Is there something my friend can do to work around this?

Hardware Model: iPhone13,4
Code Type: ARM-64
OS Version: iPhone OS 14.4 (18D52)

Exception Type: SIGTRAP
Exception Codes: TRAP_BRKPT at 0x19d447a18

Crashed Thread: 0

Thread 0 Crashed:
0 libswiftCore.dylib 0x000000019d447a18 _assertionFailure(_:_:file:line:flags:) + 492
1 SwiftUI 0x00000001a011c52c ViewCache.commitPlacedChildren(from:to:) + 3032
2 SwiftUI 0x000000019ffc8eb4 specialized IncrementalChildPlacements.updateValue() + 1384
3 SwiftUI 0x00000001a00e6fbc partial apply for specialized + 24
4 AttributeGraph 0x00000001c2cbba50 AG::Graph::UpdateStack::update() + 492
5 AttributeGraph 0x00000001c2cbbe84 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, bool) + 332
6   AttributeGraph 0x00000001c2cc5088 AG::Subgraph::update(unsigned int) + 884
7 SwiftUI 0x00000001a07d1cdc GraphHost.runTransaction() + 172
8 SwiftUI 0x00000001a07d4e1c GraphHost.runTransaction(_:) + 92
9 SwiftUI 0x00000001a07d37a8 GraphHost.flushTransactions() + 176
10 SwiftUI 0x00000001a07d4db4 closure #1 in closure #1 in GraphHost.asyncTransaction<A>(_:mutation:style:) + 24
11 SwiftUI 0x00000001a02a3168 partial apply for closure #1 in ViewGraphDelegate.updateGraph<A>(body:) + 28
12 SwiftUI 0x00000001a0726e9c closure #1 in ViewRendererHost.updateViewGraph<A>(body:) + 108
13 SwiftUI 0x00000001a071de7c ViewRendererHost.updateViewGraph<A>(body:) + 92
14 SwiftUI 0x00000001a029f6d0 ViewGraphDelegate.updateGraph<A>(body:) + 80 
15 SwiftUI 0x00000001a07d4d84 closure #1 in GraphHost.init(data:) + 124 
16 SwiftUI 0x00000001a07d66f0 closure #1 in GraphHost.asyncTransaction<A>(_:mutation:style:)partial apply + 40
17 SwiftUI 0x00000001a02c2b98 thunk for @escaping @callee_guaranteed () -> () + 28
18 SwiftUI 0x000000019ff91a10 static NSRunLoop.flushObservers() + 148
19 SwiftUI 0x000000019ff91974 closure #1 in closure #1 in static NSRunLoop.addObserver(_:) + 16
20 SwiftUI 0x000000019ff8c4b4 specialized thunk for @callee_guaranteed () -> (@error @owned Error) + 24
21 libswiftObjectiveC.dylib 0x00000001bfcc3f30 autoreleasepool<A>(invoking:) + 64
22 SwiftUI 0x000000019ff91954 closure #1 in static NSRunLoop.addObserver(_:) + 64
23 SwiftUI 0x000000019ff91aac @objc closure #1 in static NSRunLoop.addObserver(_:) + 56
24 CoreFoundation 0x0000000199798358 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36
25 CoreFoundation 0x00000001997925c4 __CFRunLoopDoObservers + 576
26 CoreFoundation 0x0000000199792b74 __CFRunLoopRun + 1056
27 CoreFoundation 0x000000019979221c CFRunLoopRunSpecific + 600
28 GraphicsServices 0x00000001b135e784 GSEventRunModal + 164
29 UIKitCore 0x000000019c1d2ee8 -[UIApplication _run] + 1072
30 UIKitCore 0x000000019c1d875c UIApplicationMain + 168
31 AppName 0x0000000100ed8444 main (main.m:19)
32 libdyld.dylib 0x00000001994526b0 start + 4

Slow House

“Slow House,” song #3, is more exercise than song. Where most songs have a structure like ABAB or ABACAB or whatever, this one is just A. Not even AAA — just A.

I wanted to get some practice recording an acoustic guitar — it’s the first GarageBand thing I’ve done where one of the parts was from a mic (a Yeti Blue). (All the previous parts are via MIDI and Apogee Jam.)

I was thinking about “Starman” by David Bowie, and how the verse starts with iim and I chords, which is a little unusual. In “Starman” it’s Gm and F — but I have a great deal of antipathy toward Gm (it can go straight to hell, if you ask me), so I used Am and G as the chords here.

And that’s all I did. No chorus, no other changes. Still, though, I like how it weaves two melodies together, and I like how it all falls apart at the end.

I also like how some of the string-like GarageBand instruments bring kind of a vocal sound — I can almost hear words in there. (But there are none.)

It’s called “Slow House” because it’s slow (as an antidote to the very fast Vampire’s Run) and because the piano is doing kind of a House thing.

Here’s the GarageBand file: SlowHouse.band.zip

It’s not until I make song #1,000 that I’ll make something people actually want to listen to more than once! I get that. I’m sharing anyway, because I think maybe it’s interesting to watch someone learn. 🐣

Vampire’s Run

My second song, “Vampire’s Run,” just finished last night, is thorny — chromatic, key-modulating, choppy-guitared — where Tie & Suit is aggressively smooth and diatonic.

I have many notes…

The Verse

I started off wanting to do something early-REM-like. The idea — kind of a bullshit idea, but I liked it anyway — was this fast arpeggio on the top three strings of the guitar: B-E-D-B E-D-B-E C-E-Eflat-C E-D-B-E A-E-C#-A E-C#-A-E A-E-B-A E-B-A-E.

REM wouldn’t have done the C-E-Eflat-C part — but the rest would have fit in. Especially that move at the end from an A chord to Asus2.

To fit some chords to this, I came up with E7, a weird C major and minor, Bmsus4, A, Asus2. The idea is that you’d play the chords as normal but with the high E string always open. (A Buck-like move.)

It’s not actually pleasing-sounding — but, again, I liked it and figured I could make something out of it.

The problem: I made the song 170 beats per minute, and I can’t actually play that lick on guitar that fast. (My personal speed limit is pretty slow, actually.) I could play it on keyboard, though, so I did. It’s the very first thing you hear in the song. I cranked up the reverb on the Steinway Grand Piano instrument, and I thought it sounded great. Like a demented Charlie Brown song.

Next up was to add percussion and a bass line. The percussion is pretty much the same thing as in Tie & Suit. The bass followed the chord roots — E C B A — except that, at the end, I threw in this little blues-scale-ish lick: A-Bflat-B-Bflat-A-G-E-G-E. Which was also total bullshit, but it totally worked, so I kept it. The interaction of that with the piano arpeggio thing just sounded really cool to me.

At this point, though, this didn’t sound like REM in the least tiny bit. It sounded like an ’80s goth instrumental. So I leaned into it — added guitar instruments Eighties Goth and Starlit Cavern. Added a bunch of echo-y things like Stutter Stack and Swirling Flutters.

The Name

Last summer I started writing a blog post called “The Vampire’s Run in the Anarchist Jurisdiction” which was about going for a run at night (instead of the day, due to the pandemic) in my neighborhood in Seattle. I wasn’t able to figure out how to write it without sounding like some very fortunate guy who had to adapt in some small way and was pretty fine about it. Wouldn’t add anything to the world, so I didn’t finish it.

But, since that title was just lying around being all goth-y, I snagged the first part of it for this song. And, well, it kinda fits — the song is very fast, and during the chorus it almost sounds like flying.

The Chorus

The song structure here is simple: verse chorus verse chorus verse chorus. But there’s a key change: the verse is in E and the chorus is in C.

This is one of my favorite modulations. The chorus gets a kind of floaty and slightly sinister sound — hence the flying.

The first time I remember encountering this was in Beltane Walk by T. Rex. I remember asking my uncle, a musician, to explain the sorcery behind that song — and when, some years later, I heard that same sorcery in Hungry Like the Wolf I recognized it right away.

(I am, by the way, a glam rock guy at my core. Give me T. Rex and Bowie and all their descendants.)

Anyway — if you hear a little Duran Duran in the C-G-F chorus, you’re not wrong.

The chords aren’t actually C-G-F, though — they’re C-G6-Fmaj7 in order to make the E note prominent all throughout the song. The melody of the chorus is just arpeggios on the piano: E-C-G, E-B-G, E-C-A, with the E repeated. While the piano in the verse is tightly horizontal, the chorus is a bit more vertical.

(There’s a little fun part right as we lead into the chorus — it sounds like that split-second when a vampire leaves ground and is a little shakily airborne. You settle in in a moment. In the first chorus we have B-F#; in the second it’s D-A-B-F#, which makes it sound like Pachelbel’s Canon; and in the third it’s A-E-B-F# — a little “Hey Joe” action.)

String and other instruments are doing a C-B-A thing during the chorus — which is cool because, as you’ll remember, that also appears in the verse. Those exact same notes, which sound somewhat discordant in the verse, sound sweet in the chorus.

The End

The song comes alive in the last third while it’s repeating the chorus before ending. I was recording the piano part for that last chorus, and I was feeling a little down that this entire song was just all these arpeggios. I started improvising — and I worked up some bits to add some more melody and passion to the song. Went all pentatonic on this shit — plus the minor third for some bluesiness. Banging on the E flat a bit.

This part comes as a surprise in the song, I think, and it was just as much a surprise to me, but it’s my favorite part. Part of me thinks you shouldn’t add so much new stuff at the end, but then I remember how “Every Little Thing She Does Is Magic” has this alternate melody at the end. And I think of how The Adversary by Crime and The City Solution — a favorite of mine from a favorite soundtrack — invents a whole new song, with a different time signature even, around the 3-minute mark.

“Vampire’s Run” ends on a simple repeated phrase which I thought sounded romantic: E D-C D C-A. Vampires love that romantic stuff.

And it ends ends on a lone E note from the piano — which sounds like a question.

If you want, you can download the GarageBand file: VampiresRun.band.zip

Computer Music

When I was a teenager I spent hundreds of hours making music on my computer. This isn’t a surprising thing to hear someone say — except that this was almost 40 years ago, and the computer wasn’t a Mac but an Apple ][ Plus.

I had an ALF II music synthesizer card with some car speakers hooked up to it. The ALF software and hardware supported nine voices, and you entered music into a staff using the computer paddles. (This page has a screenshot showing what that was like.)

Though it was a very slow way to work, and limited to beeps and bloops with varying properties, it was a miracle to me as a teenager. I took so much pleasure in layering the instruments to get something way beyond what I could perform on guitar or piano.

I stopped before turning 17. I don’t remember exactly why. Probably just spending more time writing words than music.

Tie & Suit

No recordings of the dozen or so songs I made exist. I remember fragments of some of them, and it’s fine that they don’t exist.

The one exception is the very last song I made, called “Tie & Suit.” I remember all of it: the chords, melody, arrangement, everything.

I had not, until “Tie & Suit,” written something with a traditional verse-chorus structure. Everything before that was more adventurous — to put it kindly — with odd chord progressions, lots of key changes, and weird structures. (I was convinced of my musical genius.)

I was frustrated that none of the songs I’d written were particularly memorable or even likable. I couldn’t play them on piano for someone else to enjoy. So I decided to write something simple and traditional.

I had a hobbling case of I-hate-top-forty when I was a teenager, and so I had to be sarcastic about this song: I called it “Tie & Suit” because I thought I was selling out creatively. (OMG the narcissism of me as a 16-year-old!)

Here’s the thing, though: writing a very simple melody with just five chords (I, IIm, IV, V, VIm) and a traditional structure worked! I don’t remember any of the earlier songs, but I remember this one perfectly well.

There’s a lesson in there, though I was too young to learn it.

GarageBand

I’ve been promising myself for years that I would allow myself to start making music again — only this time on a Mac with GarageBand. And so I did, just a few weeks ago. (This is my first time using GarageBand other than recording a couple tracks for James Dempsey last summer.)

I started where I left off, with “Tie & Suit.” Here’s a version where I tried to recreate what it sounded like on my Apple ][ Plus 37 years ago. It still ends up sounding more sophisticated than the original — it’s hard to make GarageBand sound like an early ’80s ALF II. I did my best (short of getting obsessed with it).

Also: it sucks. I know the song sucks. It doesn’t matter! I was 16 when I wrote it, and now I’m learning GarageBand and having fun.

The next thing I did was to try and make a modern version that’s still true to the original. “Tie & Suit 2021” also sucks — but it was so much fun to make!

I am now completely addicted to GarageBand. The pleasure of layering instruments together, picking their parts, and letting it play is every bit as intense as it was when I was 16 on that primitive gear. It’s hard to say that about most things! But this is just fucking wonderful.

URLSession’s Delegate Queue Should Be the Main Queue

Consider this line of code from RSWeb, a framework NetNewsWire uses:

urlSession = URLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: OperationQueue.main)

The delegateQueue parameter specifies the queue for all delegate callbacks from URLSession — and here I’ve just gone and made it the main queue.

Some of you are screaming. I can hear you: “Brent, Brent, Brent — you’re going to block the main thread! Don’t do it!”

Let’s Back Up and Review the Documentation

The documentation says of the delegateQueue parameter that it’s…

An operation queue for scheduling the delegate calls and completion handlers. The queue should be a serial queue, in order to ensure the correct ordering of callbacks.

(Pause right here and go check your own code to make sure you’re actually using serial queues. There’s a good chance you’re not.)

Given that the delegate callbacks should be on a serial queue, those callbacks should return as quickly as possible so that they don’t block subsequent calls.

You may have some expensive things to do — NetNewsWire, for instance, does RSS parsing and database updating. Those things should be done on separate serial queues — they should not be done on the delegate callback thread, because you don’t want to block it.

In other words, this all means that your delegate methods should be so fast that they wouldn’t block the main thread.

So Just Use the Main Thread

Your code that uses URLSession almost certainly has some data structures that do things like map a task identifier to some model object of some kind. You could go to lengths to make sure this is all thread-safe — and hope and pray nobody messes it up six months from now — or you could take the easy, safe route and go main-thread-only with that code.

That’s what we do with NetNewsWire. (And did with Vesper and other apps.)

It’s important to know I’m a performance junkie and a stability junkie — and with this practice I satisfy both.

iOS Jobs at Audible

We could be co-workers! I love working at Audible, and I think you would too. Plus — no small thing — you’d be working on an app that means so much to millions of people.

Scroll down on this page to find a list of jobs (plus a link to a longer list). On the iOS team we have several engineering positions, a QA engineering position, and a software developer manager position.

New Domain for NetNewsWire

I was not foresighted enough, back in the early 2000s, to register the netnewswire.com domain — and so, of course, somebody else bought it with the hopes of selling it to me.

(These days the first thing you do is register the domain name. But that wasn’t as much a thing back then.)

I’ve been long resigned to never own that domain name. But then, just a few days before Christmas, I got an email from Ben Ubois, founder and developer of Feedbin, saying that he’d bought it for me. We transferred the domain pretty quickly after.

And then, this weekend, I got the new site set up — and now you can find NetNewsWire where it always should have been: netnewswire.com.

Thanks to Ben!

Early Test Build: NetNewsWire 6.0d4 for Mac

The app is made of cat’s claws and fury. I try my damnedest to warn you off:

You should probably skip it. It’s not a beta. It’s not even an alpha. It’s a d release — where d, which used to stand for development, now stands for dangerous.

…and…

…let us satisfy your curiosity in advance: it’s just an app. It’s got some more features. You know the story, and you don’t need to run this if you’re just curious.

With that out of the way: the team has been doing great work! This is the first build with a Big Sur UI and app icon. It’s universal (Intel and Apple Silicon). It adds syncing via iCloud, Inoreader, NewsBlur, and others. It has special support for Twitter and Reddit feeds. Etc.

But I really do mean it when I say it’s early and dangerous. I’d like your help testing, but I need you to know it could be quite rocky and we may not have time to help you. You could lose data. You’d be doing a favor for the team which we have no way to repay — other than by eventually releasing the best app we can.

I’ve been haunted since hearing, in the early days of the pandemic, that if we all wore masks for six weeks this thing would be over.

I was there. I’ve done that for six weeks, and another six weeks, and another. And now it’s worse than ever. It’s a challenge not to be angry.

There are healthy, uninfected people right now, today, who are excited for the vaccine and who will die before they get it.

Bogus Code Signing Crash

For a few people, NetNewsWire for Mac crashes on startup — and the crash log erroneously blames an invalid code signature.

If it were truly invalid, the app wouldn’t launch for anybody. But it launches fine for almost everybody.

This started with macOS 10.15.4 and continues in macOS 11. We’ve posted more details on our issue tracker at GitHub.

Does anybody have any ideas for how to work around this?

When Are We Back To Normal?

I’m trying to figure out when we’ll be back to something like normal. I’m thinking of a few things:

  • Biden’s goal is 100 million doses in his first 100 days
  • The vaccines require two doses
  • There are 330 million people in the United States
  • Dr. Fauci has said that we’ll achieve herd immunity once we have 70-85% of the population vaccinated

Let’s say we achieve herd immunity, and some kind or normalcy, at around 250 million people vaccinated, which is just over 75%.

Since each person requires two doses, that’s 500 million doses.

The pace Biden is aiming for is 1 million doses per day. If we’re able to achieve and sustain that pace starting late in January — which is not at all a sure thing — we’ll have administered 500 million doses around mid-year 2022.

I keep hearing people talk optimistically about April or May of 2021. Me, I’m hoping to be able to see my family for Thanksgiving and Christmas 2021, but I’m not counting on it as a sure thing.

We’re going to need to go much faster with the vaccines. To reach 75% of the population by, say, Labor Day, in time for kids to go back to school, we’re going to need to administer 500 million doses by mid-August, about seven months after Biden’s inauguration. (Remember that immunity is ramped up about two weeks after the second dose.) To make this happen we’ll need to administer 2-2.5 million doses per day.

I don’t see how we get there by counting on local drug stores to administer most of the doses. I suspect we’re going to need to use parks and high school football fields — big, open spaces where large crowds can line up safely. And we’re going to need to do it day after day, with no days off.

(Is any of my math wrong? There’s no point in being overly-precise here — but please tell me if I’ve made some error that changes things significantly.)

I remember Rudolph the Red-Nosed Reindeer as my favorite of the Christmas specials — as the truly great of the genre, as the Superman of Christmas specials.

And then we watched it last night, for probably the first time this century. It was brutal.

The story was pretty rough to start with: mutant child laborer is shunned until the CEO finds a way to exploit his difference, and only then do his peers accept him. And we’re supposed to take that as a happy ending.

But there’s something far, far worse that I had utterly forgotten.

Here’s the scene: the Abominable Snow Monster is threatening Rudolph’s family. Yukon Cornelius causes a boulder to fall on the monster’s head and he passes out. And then — here’s where Sheila and I both gasped — Hermey, the elf who, charmingly, wants to be a dentist, pulls out all of the snow monster’s teeth. The teeth are shown, pulled out by the roots, littered on the snow.

Hermey is a fucking war criminal. We’re shook.

Apple’s SSL Metrics Is Hanging My App

We’ve been getting some reports that NetNewsWire for Mac will hang sometimes. A sample will report something like this:

Dispatch Thread Hard Limit: 512 reached in 1580 of 1580 samples -- too many dispatch threads blocked in synchronous operations

And there will be hundreds of threads labelled com.apple.network.boringssl.metrics_queue.

Here’s an example, with sample report, on our bug tracker.

What I think is happening: these Apple metrics reports are happening once per download per feed. So, if you have 1,000 feeds, then there are 1,000 metrics reports for a given download session. If those reports don’t complete quickly enough, then you get this thread explosion.

So… I could slow down our feed downloader so that this is less likely to happen, so that the metrics reports don’t back up so much. I don’t really want to slow down refreshing, though, but I may have no choice.

Luckily, most people don’t have the number of feeds it would take to trigger this. But, still, that’s not good enough — NetNewsWire should never hang for any user.

The Big Sur Sneeze

This has happened to me a few times. As I’m using my 2019 16" MBP, it lets out, at some random moment, a startlingly aggressive “Fehhhhh,” and then it shuts down.

It sounds as if the fan goes to 11 for about a second, and then it turns silent and dark.

To be clear: it’s completely unexpected. This is not happening when I shut down the computer. It happens whenever… it wants? Is bored? Is tired? I dunno.

So far I’ve seen this only on one laptop, and that laptop is running Big Sur. I tweeted about it, and found that I’m not the only person who sees this. James Dempsey calls it “the Big Sur Sneeze.”

My aunt Jen has narrated a book — Mermaid Eclipse by N.E. Carlisle — and it’s available on Audible, where I work. I’m so proud, and I hope this is the first of many for her. 🎙🎉

Archive