Categories
Technology

Wrapping UserDefaults

UserDefaults, formerly NSUserDefaults, is a pretty handy thing. Simply put, it’s a lightweight way of storing a little bit of data — things on the order of user preferences, though it’s not recommended to throw anything big in there. Think “settings screen,” not “the image cache” or “the database.” It’s all based up on the Defaults system built into macOS and iOS,1 and it’s a delightfully efficient thing, from the docs:

UserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default value. When you set a default value, it’s changed synchronously within your process, and asynchronously to persistent storage and other processes.

How handy is that! All the work of writing to disk, abstracted away just like that. Neat!
Now for the downside: it’s got a very limited range of types it accepts.2 Admittedly, one of these is NSData, but it can be a bit annoying to do all that archiving and unarchiving all the time.
One solution I use is writing a wrapper on UserDefaults. Swift’s computed properties are a very neat way to do it, and any code you write elsewhere in your project will feel neater for it.
The basic idea is this:


There you go: you’ve got an easy accessor for your stored setting.
Of course, we can make this a lot neater; we’ll start by wrapping it up in a class, and make a couple tweaks while we do that:

First, we made a variable to point at UserDefaults.standard instead of doing it directly. This isn’t strictly necessary, but it makes things a lot easier to change if you want to switch to a custom UserDefaults suite later.3
Secondly, we pulled the string literal out and put in a variable instead. Again, this is more about code maintainability than anything else, but that’s certainly a good thing to be working for. Personally, I tend to wrap all my keys up in a single struct, so my code looks more like this:

That’s a matter of personal taste, though.
You might also have noticed that I made both the keys and the UserDefaults.standard private — I’ve set myself a policy that any access of UserDefaults that I do should be via this Settings class, and I make it a rule that I’m not allowed to type UserDefaults anywhere else in the app. As an extension of that policy, anything I want to do through UserDefaults should have a wrapper in my Settings class, and so private it is: any time I need a new setting, I write the wrapper.
There are a few more implementation details you can choose, though; in the example above, I made the accessors static, so you can grab them with Settings.storedSetting. That’s a pretty nice and easy way to do it, but there’s a case to be made for requiring Settings to be initialized: that’s a great place to put in proper default values.4

In that case, accessing settings could be Settings().storedSetting, or

You could also give yourself a Settings singleton, if you like:

I don’t have a strong feeling either way; singletons can be quite useful, depending on context. Go with whichever works best for your project.
And finally, the nicest thing about writing this wrapper: you can save yourself a great deal of repeated code.

Or, if you don’t want to have a default return, make it optional, it’s not much of a change:

You can also do similar things with constructing custom classes from multiple stored values, or whatever else you need; mix and match to fit your project.
(Thoughts? Leave a comment!)


  1. If you’ve ever run defaults write from the Terminal, that’s what we’re talking about. 
  2. If it matters, it’s also not synced; the defaults database gets backed up via iCloud, but if you want syncing, Apple recommends you take a look at NSUbiquitousKeyValueStore
  3. If you want your preferences shared between your app and its widget(s), or between multiple apps, you need to create a custom suite; each app has its own sandboxed set of defaults, which is what UserDefaults.standard connects to. 
  4. UserDefaults provides default values, depending on types, but they may not be the same defaults that you want. If you want a stored NSNumber to default to something other than 0, you’ll need to do that initial setup somewhere. 
Categories
Tools

Recipes

Cooking! Once you’ve figured out the basics (don’t put stuff in the oven and forget about it, the result is, at best, your house smelling like burnt sadness for a while), it can be pretty fun.1
A lot of the cooking you do can be “let’s see what’s in the fridge and pantry and make something out of that,” but there’s also a lot to be said for working from a recipe.2
You can, of course, go old-school, have a huge stack of cookbooks and magazine clippings and handwritten notecards. Personally, I’d call that giving in to my pack-rat tendencies a bit too much, so I prefer to go digital.3
My recipe management software of choice is Paprika; they’ve got a Mac app, too, and I believe a Windows app?4 Regardless, it’s pretty easy to put stuff into, and they’ve got some nice stuff for actually cooking with (check ingredients off as you go, automatic conversions, multiple timers, it’s almost like the app was made for this).
When you first open it up, it can be a bit empty, and their suggestion of “putter around the internet and find some stuff to get started” didn’t quite work for me. You remember that mention of cookbooks and clippings and notecards? That’s what we used to have; now it’s a much more compact setup, and I’m quite willing to share. About 900 recipes, neatly organized to help you start off your collection. Enjoy!


  1. And, as a fun bonus, it’s generally cheaper than buying ready-made food! 
  2. Especially if you’re baking; cooking is an art, baking is a science. 
  3. Same amount of stuff, but much easier to search through! And the storage is a lot cheaper, too. 
  4. You can tell how long it’s been since I used Windows, not by the fact that I don’t know, but by the way that I don’t know if they’re called apps on Windows or not. Program? Software? Who knows. 
Categories
App

Fluidics 1.3: the Subscription Update

I was originally going to call this one “the widget update,” but that felt a bit dishonest, because that’s not the biggest user-facing change of the update.
As somebody who wants to have a nice, long career making software for people to use, I’m rather invested in the idea that it should be possible to make a living by… making software for people to use. The original business model for the App Store, then, was a bit iffy: the user buys your app and then they have it indefinitely. Good for them, except with the developer no longer making money, they no longer have any incentive to maintain the app.1 Bad news for the user, as the app is no longer getting new features, or even maintained to stay functional on the latest versions of the operating system.
Which is why I’m rather a fan of the subscription mechanic that Apple started giving developers recently. Ongoing revenue means ongoing support; that’s why, for example, I jumped at the chance to support my favorite writing app when they shifted to a subscription model.
With this update, I’m adding a subscription to Fluidics. Thus, the title of the update; it’s definitely not a hidden thing I’m doing here.
I’m also not taking any features away; everything that was available for free in 1.2 remains free.2 The subscription is titled ‘Pro,’ and the goal is for it to provide access to a variety of new features. Initially, there are two: with a Pro subscription, you can apply your own multiplier to your daily goal, from 0.5 to 1.5; and there’s now a second widget option, displaying your progress towards your goal and a single Quick Add button that can cycle through all of your Quick Adds with a tap.
I also want it to be pretty cheap, so it’s about as low as it can go: a dollar a year.
These aren’t the only Pro features I have planned — I’d like to add a few more things that I think will be quite handy. There will be new features for the free version of the app, too; in this update I’ve added a new ‘Goal’ card (in the Settings screen) that shows how the app is calculating your goal. It’s color-coded, I’m quite proud of it.
So that’s the long and short of it: in order to fund ongoing development of the app, there’s a new $1/year subscription that’ll get you some ‘Pro’ features; the core functionality is still free, but if you want a bit more power, it’s there at a very reasonable price.
As always, thank you for reading, and I hope you’ll download Fluidics; it’s free on the App Store.


  1. For a while, this worked out okay, thanks to the explosive growth of the iPhone; the growing customer base of the App Store meant there was functionally infinite growth of your target market. Now that some absurd proportion of the world population owns a smartphone, though, that growth has slowed down. 
  2. I am, admittedly, kicking myself a little about not keeping the “different units per Quick Add” as a ‘pro’ feature, but oh well, I decided I wasn’t going to take anything away from anyone. 
Categories
Technology

iOS Notification Routing

The other day I was thinking about the way iOS handles notifications; the new Do Not Disturb stuff in iOS 12 is a good start, but it’s still rather lacking. It’s a fun thought exercise: say you’re Jony Ive or whoever, and you’re setting out to redesign the way that notifications work, from a user standpoint.1 How do you make something that offers advanced users more power… but doesn’t confuse the heck out of the majority of your user base?
After a while dancing around the problem, I came to the conclusion that you don’t.23
Instead, imagine something more along the lines of Safari Content Blockers. By default, the existing system stays in place, but create an API that developers can use to implement notification routing, and allow users to download and install those applications as they so desire.4
Obviously, this would have some serious privacy implications — an app that can see all your notifications? But hey, we’re Jony Ive, and Apple has absolute control over the App Store. New policy: Notification routing apps can’t touch the network.5 And, to prevent any conflict of interest stuff, let’s just say that the routing apps aren’t allowed to post notifications at all.
Alright, we’ve hand-waved our way past deciding to do this, so let’s take a look at how to do it, shall we?
Let’s start with the way notifications currently work. From UNNotificationContent we can grab the properties of a notification:


For proper routing, we’ll probably want to know the app sending the notification, so let’s add the Bundle ID in there, and we’ll also give ourself a way to see if it’s a remote notification or local.

Alright, seems nice enough.6
Next up, what options do we want to have available?
1. Should the notification make a sound?7
2. Should the notification vibrate the phone?
3. Should the notification pop up an alert, banner, or not at all?
4. If the user has an Apple Watch, should the notification go to the Watch, or just the phone?
5. Should the notifications show up on the lock screen, or just notification center?
6. Finally, a new addition, borrowing a bit from Android: which group of notifications should the notification go into?8

Alright, that should be enough to work with, let’s write some code.


Not a complex object, really, and still communicating a lot of information. I decided to make the ‘group’ aspect an optional string — define your own groupings as you’d like, and the system would put notifications together when the string matches; the string itself could be the notification heading.9
And with that designed, the actual routing could just be handled by a single function that an application provides:

And with that, I’d be free to make my horrifying spaghetti-graph system for routing notifications, and the rest of the world could make actually sensible systems for it.
Thoughts? There’s a comment box below, I’d love feedback.


  1. I haven’t done much work with the UserNotification framework, so I’m not going to be commenting on that at all. 
  2. I spent a while mentally sketching out a graph-based system, somewhere between Shortcuts and the pseudo-cable-routing stuff out of Max/MSP, but realized pretty quickly that that’d be incredibly confusing to anyone other than me, and would also look very out of place in the Settings app. 
  3. As a side concept, imagine that but implemented in ARKit. “Now where did I put the input from Messages? Oh, shoot, it’s in the other room.” 
  4. Unlike Safari Content Blockers, though, I think this system would work best as a “select one” system, instead of “as many as you like, they work together!” thing. Mostly because the logistics of multiple routing engines put you back in the original mess of trying to design data-flow diagrams, and users don’t want to do that. Usually. 
  5. I’d call this less of an ‘App Store’ policy and more of a specific entitlement type; if you use the ‘NotificationRouting’ entitlement in your app, any attempt to access the network immediately kills the application. 
  6. Of course, those last two additions wouldn’t be things that you’d be able to set while building a UNNotificationContent object yourself, so perhaps we should be writing this as our own class; UNUserNotification perhaps? 
  7. We’ll assume that setting notification sounds is handled somewhere else in the system, not by our new routing setup. 
  8. This would be at a higher level than iOS 12’s new grouped notifications (the stacks), more like the notification channels in Android: categories like ‘Work’, ‘Family’, ‘Health’, and so on. 
  9. Since we’re Jony Ive, and everything has to be beautiful, we’re presumably running it through some sort of text normalization filter so people don’t have stuff going under the heading “WOrk” 
Categories
Playlist

Playlist of the Month: October 2018

Happily, the new Shortcuts update came out yesterday that makes my “get all these links” Shortcut work again. Have you downloaded iOS 12.1 yet?
Desert Rose – Jay Brannan 1
Silhouette – Aquilo
Oceans Away – A R I Z O N A
Antes de Morirme (feat. Rosalía) – C. Tangana
start//end – EDEN
Real – Majik
Stronger – Kanye West 2
Lucky Strike – Troye Sivan
No Eres Tú – Jesse Baez & C. Tangana
What a Heavenly Way to Die – Troye Sivan
NFWMB – Hozier
Loyal – ODESZA
lovely – Billie Eilish & Khalid
Coldplay (feat. Vic Mensa) – Mr Hudson
Opps – Vince Staples, Yugen Blakrok
Since the Day I Was Born – Lostboycrow
COPYCAT – Billie Eilish
Boy – ODESZA
Line of Sight (feat. WYNNE & Mansionair) – ODESZA
Can’t Forget You – Mr Hudson
Lyla – Big Red Machine
Higher Ground (feat. Naomi Wild) – ODESZA
The Catalyst – LINKIN PARK
Clarify (feat. Fractures) [Tinlicker Remix] – Lane 8
Bluebird – Lane 8 & Anderholm
Ibiza (feat. Romeo Santos) – Ozuna 3
Hide and Seek – Kodaline
See – Tycho
Not Alone – LINKIN PARK 4
Don’t Come Around – Kodaline
Born Again – Kodaline
Happier – Marshmello & Bastille 5
Angel – Kodaline
Across the Room (feat. Leon Bridges) [Tycho Remix] – ODESZA
Cheap Thrills (feat. Sean Paul) – Sia 6
Hell Froze Over – Kodaline
Sad Season – Gavin Haley
you should see me in a crown – Billie Eilish 7
Optimistic – Lontalius 8
Gold – Fyfe & Iskra Strings
Besos Mojados (feat. R.K.M. & Ken Y) – Ozuna
Push for Yellow (Shelter) – Valley
La Modelo (feat. Cardi B) – Ozuna

  1. I think this one isn’t gonna make it into next month’s list, it’s had a good run though. ↩︎
  2. Probably I should get rid oof the last fo the Kanye in my playlists, he’s gone a bit off ↩︎
  3. Because of this song I wound up adding Ozuna’s two most recent albums. Sadly, nothing’s gotten to this level yet, but still, I’m hopeful. ↩︎
  4. I believe all the proceeds from this one are still going to charity, so like… listen for a good cause! ↩︎
  5. This is, like, the opposite of “Optimistic”, further down the list, and it’s kinda nice. ↩︎
  6. I genuinely have no idea if this is the original or not, I’d heard like four different covers of this song before I ever heard Sia sing it. ↩︎
  7. I love both the music and the lyrics, this song is great. ↩︎
  8. Musically I like this, but I’ve been trying to avoid listening to the lyrics because, from what I’ve actually paid attention to, I think the song is basically “white boy Isn’t Sad about being in the friendzone” ↩︎
Categories
Technology Tools

Automatic OCR with Hazel

I recently got a copy of Hazel and have been doing a bit of tinkering around with various ways to automate my file management. Because, y’know, I can do it by hand, but why would I when I can make a computer do it for me? That’s the whole point of computers, after all.
I have a great deal of PDFs — something about scanning every paper, handout, receipt, or bit of mail I’ve received in the past six years or so does that. And if you have a commercial-grade scanner, it can be pretty easy to automate that stuff with Hazel, as the scanner will run everything it scans through Optical Character Recognition, and the PDF you’ll get will be nicely searchable.1
Unfortunately, the scanner I’ve got, while a pretty good one, is in a different price tier than the ones that’ll do the automatic OCR, so I needed a way of doing that after the fact.
There are some guides to doing that, such as this one,2 but they tend to require either Acrobat Pro or PDFPen Pro, which both have price tags above the “a couple hours of tinkering and no money” that I was hoping to spend on this project.
Throw a few computer science keywords on what you’re Googling, though, and you’ll find stuff that’s more in that vein.3 So, compiled here after I used Chase as a guinea pig, a guide to putting together automated OCR for free.4

Prerequisites

Before we can automate OCR, we need a few things installed. Open up Terminal, and let’s go.
sudo easy_install pip
(For those of you who didn’t put a few years into classes on computer science, I’ll try to explain as I go along. That first word, sudo, means “super user do”, basically; it’s the Admin Override for terminal commands. Be careful with it, you can make quite a mess tinkering with it. The next bit, easy_install, is part of the version of Python that comes default with macOS. pip is what we’re telling easy_install to install; ironically, pip is the modern version of easy_install.5)
The first time you use sudo in a Terminal session, you’ll be prompted for your password; if you’re not an administrator on the mac you’re using, you’ll need an administrator password. That’s a good opportunity to check with the administrator if this is something you should be doing at all.
Once pip is done installing, we’re going to get another installation helper, Homebrew:
sudo /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Again, this is just installing a piece of software, Homebrew.

Components

Now that we’ve got the infrastructure built, we’re going to install the components that the OCR system uses.
brew install tesseract
brew install ghostscript
brew install poppler
brew install imagemagick
(If any of those fail, you can try to rerun them with sudo added to the front, i.e. sudo brew install tesseract.)
For reference: Tesseract is the actual OCR engine, Ghostscript makes it easier to interact with the PDF format,6 Poppler is similarly PDF-related, and ImageMagick handles conversion between basically any types of images.
Finally, we’ll use pip to install a specific version of another:
sudo pip install reportlab==3.4.0
ReportLab is yet another PDF-related library, but version 3.5.0 has some compatibility issues with the OCR system.

Installation

Finally, we’ll get the actual thing that ties these all together:
sudo pip install pypdfocr
PyPDFOCR is a lovely open-source project that ties all these components together into a single thing. Once it’s installed, you can use it from the terminal:
pypdfocr {filename}, where you replace {filename} with the non-OCR’d version of the file you want in OCR’d form.7 It’ll take a bit to run, but once it’s done, you’ll have a file (named {filename}_ocr.pdf) that contains, hopefully, the text of the document you scanned.89
Go ahead and test it; if you get an error about the file not being found, see if the file name or directory structure included a space. If it did, tweak the command a bit: instead of pypdfocr {filename} you’ll need to do pypdfocr "{filename}".
You may also get an error that mentions File "/Library/Python/2.7/site-packages/pypdfocr/pypdfocr_pdf.py", line 190… and a bit more after that. If it’s AttributeError: IndirectObject…, then you’ll need to tweak part of the code.10
cd /Library/Python/2.7/site-packages/pypdfocr
sudo nano pypdfocr_pdf.py
That’ll open up nano, a very lightweight text editor. Press control+W, type in orig_rotation_angle = int(original_page.get and hit return; this will take you to the line we want to edit. It’ll read orig_rotation_angle = int(original_page.get('/Rotate', 0)) — we want to change it to orig_rotation_angle = int(original_page.get('/Rotate', 0).getObject()) by adding .getObject() before the last close-paren.
Once you’ve done that, press control+X, then hit return again. Try OCRing something again; it should work this time.

Using Hazel

Now all you need to do to have Hazel automatically OCR a PDF is, in the actions, add a “Run shell script” action, use “embedded script”, and in the ‘edit script’ bit, put in pypdfocr "$1".
Keep in mind, this doesn’t replace the PDF in place, it’ll create a copy with _ocr added to the end of the name. If you’d like the original to be deleted once it’s done, rather than having Hazel do it, just add a second line to the embedded script: rm "$1"
You’ll probably want another rule to move the OCR’d versions somewhere else; while you’re building that, you can also use the ‘rename’ action to remove the _ocr bit, just tell it to replace “_ocr” with “”.
Have fun automating!


  1. And, as a result, useable for Hazel sorting by way of the ‘contents’ filter. 
  2. I was hoping to link to Katie Floyd’s original post about it, but her website is down at the moment, so I guess I won’t be doing that. 
  3. Technically speaking, I think all I added was “site:github.com”, but that did the trick. 
  4. This assumes you have a Mac, since you’re working with Hazel, and that you’re willing to do a bit of tinkering in the terminal, which I also kinda assumed, since you’re working with Hazel. 
  5. I think that’s irony; I was a computer science major, not an English major. 
  6. “the Printable Document Format format” 
  7. Tip: you can type pypdfocr  (including the trailing space) and then drag-and-drop the PDF from Finder into the Terminal, and it’ll automatically fill in the filename. If any part of the path includes a space, though, it’ll fail, so for filenames or folders that contain spaces, do pydpfocr "{filename}" – type pypdfocr ", drop in the file, and then ", and then hit enter. 
  8. Caveat: Tesseract isn’t perfect, especially with regard to the formatting, so don’t expect this to give you a perfectly-formatted version of whatever you scanned. That said, the process is lossless: {filename}_ocr.pdf is built by taking the original PDF file and then adding an invisible text layer over the analyzed text, so you won’t lose any information by doing this, you just might not gain anything useful. 
  9. Note that it’ll spit {filename}_ocr.pdf out not necessarily where the original file was, but wherever the Terminal session currently is; if you’re unsure about where that is, you can use pwd to have it displayed, or just open . to open it in Finder. 
  10. Don’t ask me why this is all “you might have to do this”, because I genuinely don’t know why this problem only pops up some of the time. 
Categories
Playlist

Playlist of the Month: September 2018

Man, I didn’t appreciate “back to school” time enough when I had it.
Desert Rose – Jay Brannan
Thin – Aquilo
Silhouette – Aquilo
All I Want – Kodaline
Follow Your Fire – Kodaline
Six Feet Over Ground – Aquilo
Babylon – Oneohtrix Point Never
You Want It Darker – Leonard Cohen
Oceans Away – A R I Z O N A
Antes de Morirme (feat. Rosalía) – C. Tangana
icarus – EDEN
lost//found – EDEN
start//end – EDEN1
Real – Majik
Stronger – Kanye West
Lucky Strike – Troye Sivan2
Crystal Souls – Headphone Activist
No Eres Tú – Jesse Baez & C. Tangana
Away from You – Sound Remedy3
You Moved Away – Death Cab for Cutie
Clouds, Not Clocks – Slow Meadow
What a Heavenly Way to Die – Troye Sivan
Stupid Mistakes – lovelytheband
Postcard (feat. Gordi) – Troye Sivan
wrong – EDEN
Nina Cried Power (feat. Mavis Staples) – Hozier
NFWMB – Hozier4
When We Drive – Death Cab for Cutie
wings – EDEN
Technologic – Daft Punk5
Loyal – ODESZA
Thought Contagion – Muse
lovely – Billie Eilish & Khalid6
Coldplay (feat. Vic Mensa) – Mr Hudson7
Opps – Vince Staples, Yugen Blakrok
Since The Day I Was Born – Lostboycrow
Zero (From the Original Motion Picture “Ralph Breaks The Internet”) – Imagine Dragons
La Ciudad – ODESZA
COPYCAT – Billie Eilish
Forest Green – Big Red Machine
Boy – ODESZA
Line of Sight (feat. WYNNE & Mansionair) – ODESZA
Can’t Forget You – Mr Hudson
Lyla – Big Red Machine
Fix You – Canyon City8


  1. Seriously, I love this one 
  2. He’s really going for that Lana Del Rey, “I plan to be young and beautiful and then die the moment either of those runs out” aesthetic 
  3. I really like this one, but it really doesn’t agree with the speakers on my phone, which is a bummer when I’m driving; we’re all spoiled by having an aux cord, these days, but I don’t have one. 
  4. “Give your heart and soul to charity/’Cause the rest of you, the best of you/belongs to me” is such a creepy, weird line, and I love it 
  5. Someone asked me “are all Daft Punk songs like this?” while I was listening to this one. 
  6. I’d kinda forgotten about Billie Eilish, to be honest, and then someone reminded me of her and I spent the next two hours just listening to whatever Apple Music had. 
  7. Sent this one to a friend. “I like the song, but I don’t like that it’s not by Coldplay.” 
  8. This wasn’t the only cover of a Coldplay song I almost included; the version of Yellow in Crazy Rich Asians almost made it in. 
Categories
Review

“Post-Capitalist Society,” or, “hindsight is fun”

Peter F. Drucker
This book was published in the early 1990s, and it’s kinda gained something by being dated. Drucker has quite a few “by the 2010s” lines in there, which are about half “wow, how did he know?” and half “oooh that’s not how that went.” To me, at least, there’s a good amount of comedy in that sort of thing, and I rather enjoyed the read.
Beyond that, I don’t have a lot to say about it, so I’ll throw out a couple quotes I pulled while I was reading it.
“Power must always be balanced by responsibility; otherwise it becomes tyranny.”
“The future may we ‘post-Western’; it may be ‘anti-Western.’ It cannot be ‘non-Western.’”
Like I said, a good deal of what he talks about has come to pass, but a good deal hasn’t, and some of what hasn’t is the sort of thing that I wish had. It’s a fun read, give it a go.

Categories
Tools

Minimalist YouTube

YouTube’s got all sorts of paid offerings now, and they sure do like advertising them. I really like the amount of full-screen ads I get in their mobile app informing me that I can watch whichever sport is in season, live, with YouTube TV; really makes you wonder why we worried about targeted advertising, if the biggest ad company in the world still hasn’t figured out that I don’t care about sports.

Now, while I don’t use an ad-blocker to stop the actual advertisements that play before the videos (I’d like the people I subscribe to to get some amount of income from their job, at least), I’m quite happy to cut out portions of the YouTube interface that annoy me. (My tool of choice for this is 1Blocker; the Mac app has all sorts of fun customizations available. Their iOS app also has the tools, but Safari Content Blockers don’t work on apps, so it’s not as helpful there.)

After spending half an hour digging around in the structure of the average YouTube page, I’ve arrived at the above version of the site: no suggested videos, no notifications or messages, and no reminders that YouTube has ways to directly take my money and route a small portion of it to the content creators I like. Basically all that I’ve left are the portions I actually use: watching videos, the Subscriptions page (I miss when you could export that to RSS), and the Watch Later list.

If that sounds like something you’d like, I organized the 1Blocker ruleset and uploaded it here. You’ll need 1Blocker installed to use it, but if you don’t have some sort of tracker-blocker going already, that’s the one I’d recommend.

Categories
Playlist

Playlist of the Month: August 2018

The problem with listening to music that’s mildly non-mainstream is that anything with a simple name is more difficult to find on iTunes.
How It Is – Majik
The Weight – Amber Run
Technicolour Beat – Oh Wonder
Desert Rose – Jay Brannan1
XO – EDEN
Thin – Aquilo
drugs – EDEN
Silhouette – Aquilo
All I Want – Kodaline
Age Of – Oneohtrix Point Never
Follow Your Fire – Kodaline
Closer – Majik
Silent Movies – Aquilo
Six Feet Over Ground – Aquilo
Babylon – Oneohtrix Point Never2
You Want It Darker – Leonard Cohen
Oceans Away – A R I Z O N A
Summertime (feat. San Holo) – Yellow Claw
The Journey – Sol Rising3
Follow – SKALE – E – TRON
X – Majik
stutter – EDEN
Confidence – Majik
Antes de Morirme (feat. Rosalía) – C. Tangana
wonder – EDEN4
icarus – EDEN
lost//found – EDEN
The Way I Am – Charlie Puth
Song For You (Mansionair Remix) – Rhye
forever//over – EDEN
start//end – EDEN5
gold – EDEN
IMPRINT – FELIX SANDMAN
Guerrera – DELLAFUENTE & C. Tangana
Bien Duro – C. Tangana6
Black Sun – Death Cab For Cutie
Real – Majik


  1. I’d argue that the only reason Jay Brannan isn’t considered a Gay Icon to some degree or another is that he specifically doesn’t want to be known as “that gay singer” which is… even more Iconic(TM), to be honest 
  2. can we just take a moment to appreciate the band’s name? it’s so delightfully weird 
  3. This one is very calming. 
  4. Given how much of this album I’ve got in this playlist, I’m gonna go ahead and make the album art the photo for this post. Why does the post need a photo, you ask? Because it’ll look better. 
  5. Top new song this month; I just really love the effect on the piano. 
  6. I’m sorta refusing to think about the lyrics of this one, because from the little bit I’ve understood from casual listening, this is such trashy pop music that I’m probably happier not knowing. 
Categories
Review

James Baldwin’s Collected Essays

James Baldwin
This is ostensibly supposed to be a book review in the way I normally do them, but that doesn’t feel like the right way to go about it. For a variety of reasons, really: firstly, because most of what I review is fiction, and this was only partially that, if at all; and secondly, because it’s just a different sort of book than I usually do.1
James Baldwin was, I’ve learned, a Figure in the civil rights campaigns. To be honest, before I started the project of reading this book, I hadn’t really heard of him. The first references I got to his work were as quotes in essays I proofread for a friend of mine; it took me a while to catch on to the fact that I was seeing the same name come up over and over. (That friend went on to write a thesis about Baldwin; I believe it’s available online, and I’d recommend reading it, if only so you get a better look at Baldwin’s work than I’ll be able to give here.)
The Essays cover a variety of things, but the core component is the relationship between Black and White in America. Which I’m hardly qualified to talk about; again, I’ll point you to that thesis, or just directly to Baldwin’s writings, because both are far better takes than anything I can come up with.
Content aside, Baldwin is a great writer, and a powerful speaker; if you get a chance, check out some of his speeches, they’re certainly on YouTube by now.
The one caveat I’ll give this book is that you shouldn’t plan on finishing it in one sitting, or even a handful; it’s a book that demands effort. Even just from the physical standpoint — it’s 800-plus pages, in the edition I have, fine print on the Bible-like thin paper. It demands endurance, and you can’t really power through it like I tend to with books; after, at most, 100 pages, I had to put it down and give my brain time to process through things, because after a while you start to feel like a river is pouring through your head, in one ear and out the other.
Which isn’t to say you shouldn’t read it, because you absolutely should. I’m glad I put the time into it, and I suspect I’ll be budgeting time for another run at it again sometime in the future.2


  1. I’ve reviewed one other collection of essays, that I can remember: “The Control of Nature”, which I adored. But that was also different; the essays were about Man’s relationship to Nature, and not Man against Man and Society, or whatnot. I dunno, I’m trying to remember terminology from the last literature class I took, which was either three or four years ago, depending on how you count things. 
  2. And, tacked on here as a footnote because I couldn’t leave it out, but I also couldn’t work it in anywhere else: a couple people who’d read his work before had lead me to believe that he was queer in the way that Shakespeare was — rumored or hinted at, but never really confirmed one way or the other. I can only assume, from that stance, that they hadn’t read the last two essays in the collection, because the final essay includes a description of a young man that begins with “We were never lovers: for what it’s worth, I think I wish we had been.”
    The essay before is even more explicit, I’d say, in that it devotes several pages to talking about Baldwin’s experiences in what are, today, equivalent to gay bars and bathhouses; perhaps my favorite part is the little editorial note at the end that consists of the year it was published and the fact that it was first published in Playboy
Categories
Review

“Openly Straight,” or, “just let this idiot be happy”

Bill Konigsberg
I was genuinely surprised to find this book on my Kindle; I knew it was one I’d been wanting for a while, but I didn’t remember actually buying it. Still, I’m on vacation, trying to work my way through the backlog of books a bit, so I shrugged and started to read.
Here’s the concept, containing no more spoilers than the Amazon blurb: Rafe is an openly gay young man living in Boulder, Colorado. And by ‘openly gay,’ I mean very; he came out in middle school, his parents threw a coming out party, his mom became president of the local PFLAG chapter, and he’s got, like, an internship kind of thing being a speaker at other high schools in the area. Not bad for a sophomore in high school.
That’s where the book starts, and it quickly leaves that point, because Rafe isn’t happy with this life. Sure, everyone accepts him as The Gay Kid, but that’s all he is. He scores the winning goal in a soccer game, and the local newspaper runs a story: “Gay Student Wins Game!” And who really likes being boiled down to one aspect of their personality?
So he leaves; gets himself accepted to an Ivy-prep boarding high school over on the East Coast somewhere. Not mentioned to the very-supporting parents and friends? The fact that he’s not going to be gay there; he’s going to let the ‘straight until proven gay’ aspect of heterosexism1 take over and get to experience life from the other side.2
Which is, honestly, a very interesting concept, but in execution, I didn’t enjoy it all that much. It felt, to me, like the book was trying to be two different things at once, and as a result, failing at both. The beginning and end are in a more literary bent, exploring some of the stuff I’d mentioned earlier. Which is a valid topic to be explored, and the way it’s handled is sufficient that, at the end of this point, I’m still going to recommend the book. Where it falls apart is in the middle; the book gets a bit distracted from that literary style and turns into a bit of a teenage romance fluff pile.
Again, not a bad thing, but the two aspects don’t work well together; the conflict of the book should be either the literary ‘man versus society’ kind of thing, or the romance ‘man versus his own idiotic self being mad at romance’ deal. Instead it’s ‘literary aspirations versus the plot arc of a romance novel,’ and both portions lose out for it. The romance novel falls apart because that’s what the literary aspect demands, and the meaning of the literary component feels cheapened by the collapsing romance.
I wish I could’ve liked this book more, but oh well. Still, it does have some valuable things to say, and I’m going to go ahead and recommend it.3 Give it a read, and maybe do a slightly better job than I did at engaging with the more thought-provoking portions.4


  1. If you don’t know what the word means, read the book, it does a better job explaining it than I can. 
  2. The first few chapters of this are actually very anxiety-inducing; minority stress is a real thing, and imagining going through it without a support network is a stressful concept. 
  3. Because, y’know, this has been such a glowing review. 
  4. Part of the issue for me, I suppose, is that all the thoughts it’s trying to provoke are conclusions I arrived at a while ago; I’m not really the target audience, I suppose. 
Categories
Review

“Smoketown,” or, “post-eco-apocalypse, but weirdly uplifting”

Tenea D. Johnson
I’m normally not a fan of post-apocalyptic stuff, because, y’know, if I want to be depressed about the world I’ll just turn on the news. This, though, wasn’t as depressing as things usually are — things have fallen apart as compared to what we’re used to, but people aren’t letting it stop them. Life goes on, even if that means city-states throughout the remnants of the US cooperating on carbon sequestration projects to try to keep Idaho from sinking.1
This was also one of those books that does an excellent job of setting up a fascinating setting without dropping into mountains of exposition. There’s never an explicit reference to what’s happened, but you can pick things out from background details pretty well; it’s tantalizing, to see little hints of things but not get a full explanation.
The story, too, is interesting, because it doesn’t treat the overall ‘apocalypse’ as the Big Problem. It’s hinted at that the various governments of the world are continuing to adapt to and prevent further problems, but the story focuses on two levels: a personal dilemma, and one enveloping just the city where the story takes place.
The personal is weird and convoluted and makes sense, eventually; the city-level is more neatly tied together. It’s quite satisfying, all told; as I was getting towards the end of the book, keeping an eye on how much of it was left, I wasn’t expecting everything to tie up as well as it did.
And I think I’ll stop there; I don’t like giving away spoilers, and this book did a better job of keeping me from guessing the ending than I usually do. Give it a read.


  1. I believe that’s an incorrect reference, technically — Idaho was mentioned as having become entirely desert, I think, and somewhere else (Louisiana, presumably) had effectively sunk into the ocean. 
Categories
Travel United States

Detroit Lake

This past weekend, I finally got a chance to visit another of Oregon’s tourist destinations: Detroit Lake. It’s a pretty cool place — used to be a valley, and then, y’know, industry happened; two dams later, there’s a lake. Normally the water level is a bit higher, but (I’m told) there was a storm early in the season, for which the folks in charge of the dam1 drained some water so they wouldn’t have overflow problems. Unfortunately for them, the fish were spawning at the time, and wound up taking advantage of the raised river level, and per the “don’t kill thousands of fish” directive, they were then required to maintain that higher river level. So the reservoir drained faster than usual, and the season got cut off earlier than usual. Bit of a bummer for the local businesses.
Presented in no particular order, some of my favorite photos from the trip:















  1. US Army Corps of Engineers, maybe? 
Categories
App

Fluidics 1.2: the Settings Update

I’m happy to announce the release of Fluidics 1.2! This update focused on the settings of the app and customizability; the quickest summary I can give is to include one of the new App Store images:

The first thing to notice is the new cards; they come up from the bottom of the screen, which is a much nicer experience on really tall devices like the iPhone X, and offer a more customizable interface than iOS built-in popup stuff.1
There’s some uses of the cards that I’m not showing here — I rebuilt the onboarding process, that initial setup you go through the first time you open the app, using this card style, and the result looks a lot nicer. There’s also some informational stuff — a new ‘about’ card, the weight/Health connection stuff, and so on — but the biggest things are the two cards in that screenshot. The first is, in my opinion, the more interesting: each Quick Add now has its own unit. If you’re content with the old system, all of them using the same unit, nothing’s changed; the text of the buttons is a bit bigger, but there’s no additional use of space. If you, like me, use a mix of units,2 you’ve now got the option to do that in one place, without needing to go over to the Settings page to switch back and forth all the time. These mixed-unit quick adds, as always, work both from within the app and from the widget.3
Next up is the new Display Settings card; this brings in features I’ve been wanting to have for a while now. Some of the original settings are still there — you can, as before, show or hide the help as you need it, and the ability to select the global display unit has been expanded to include liters as well as mililiters.4 There’s some new settings in there, too: you can choose which page of the app will come up when you first open it — useful if you’ve got your Quick Add values set just right to always work with the widget, and you only need to get into the app to add the occasional weird amount via the Custom Add page. You’ve also got the option to hide the goal display — you’ll still get the nice filling-up of the background, but without the actual number right there, it’s a lower-pressure environment.5 Finally, you can disable the animation of the background; though I spent quite a while making sure it’d work, I know that some people don’t actually want lots of animations going on.6
I also put a bit of polish on the way the Health connection works, so now it’s a single button in Settings that opens up a different card depending on the context — if you haven’t done all the connecting to Health, it’ll give you the option to do that, or leave things as they are; if it is connected to Health, but you haven’t got your weight logged there, you can continue using Fluidics’ built-in weight handling stuff. That’s been improved, as well, and now lets you pick units yourself, instead of going with the default for your region.7
Not mentioned in the release notes, but something I feel like mentioning here, is that I’ve done a bit more groundwork to prepare the app for eventual internationalization. There’s still a lot more ground to cover in that regard, though, so probably I won’t be adding additional languages for another couple versions.8
All that said, I’m pretty happy with where this version is, and I’m also excited to start work on the next big update; the feature list I’m aiming for is pretty neat. Fluidics remains free on the App Store, so please, give it a download.


  1. The specific implementation I’m using is this open-source project; I liked the way the API worked, though the documentation is a bit out of date. 
  2. Because ‘Murica. 
  3. Unfortunately, I had to reset the quick add settings as a result of this transition; the new way they’re stored is thoroughly incompatible with the old way. If you were just using the default ones, you won’t notice any change, but I wasn’t able to come up with a good way to transfer over customized settings. The issue is people like me, who used fluid ounces sometimes and milliliters other times; there’s no good way to combine eight possible options into four spaces without messing something up for someone. 
  4. I also tweaked the way amounts are displayed, so using mixed unit stuff doesn’t result in a downright stupid amount of decimal digits; I don’t think it really matters to anyone that you’ve had 101.327 fluid ounces to drink today, probably you’re alright with just 101.3. 
  5. There’s probably a joke in there about hydraulic pressure, but I’m too lazy to come up with it. 
  6. By default, it’s on, unless you have ‘reduce motion’ enabled on your phone, in which case it’ll default to having the animation disabled. That said, if you’re like me and have ‘reduce motion’ on just to get rid of the somewhat-nauseating parallax effect on iOS’ home screen, you can turn Fluidics’ animation back on while still leaving the global ‘reduce motion’ setting on. Nitpicky details, woo! 
  7. Shoutout to the UK, who can now use pounds, kilograms, or stone for weights; I may mock the US for our weird use of mixed units, but I think the UK is even worse about that. 
  8. At that point, it’ll probably be Spanish and German, since those are the ones I can manage without hiring a translator, but if anyone really vehemently wants a different language, feel free to leave a comment and I’ll see what I can do.