Author Archives: Michael Descy

Harman Kardon Soundsticks II Speaker System

In my mid 20s, I decided to move from boring (but nice) suburban Connecticut back to the Boston area where I went to college. It was a chance to reinvent myself, which is something I really needed to do at the time.

In the process, I replaced a lot of my belongings—cheap things or hand-me-downs that I had since my college days—with newer, better versions. I replaced nearly everything I cooked with and ate with: dishes, pots and pans, and small appliances. I bought a new wardrobe and got rid of my ratty old T-shirts and jeans. I traded up from a slow and struggling Dell tower PC to a sleek, fast, white MacBook (my first Mac!). I also traded up from my old, busted Altec Lansing computer speakers to the cool, futuristic Harman Kardon Soundsticks II that I saw in the Apple Store.

The Soundsticks’ clear plastic construction made them almost invisible. Their clear, light-up subwoofer looked like a bioluminescent jellyfish floating atop the tangle of wires under my desk. Their capacitive touch volume control was futuristic, too, but really hard to control; I mainly relied on my MacBook’s volume control instead.

In my cool, urban apartment, I played music through these cool, stylish speakers for hours and hours each day as I worked on my new MacBook (and on my work laptop, side-by-side). They sounded much better than my prior Altec Lansing computer speakers, but mostly they just looked better. I found that, at loud volumes, they didn’t really fill the room how I would have liked them, but I rarely played them that loud anyway, considering they were sitting on the desk I was working at.

During this time, I stopped buying CDs and started buying music online. I got into indie rock very heavily, mainly because I could get their tracks at great prices (25 cents per track) though eMusic. I first heard Okkervil River, Spoon, The Avett Brothers, The Apples in Stereo, Bright Eyes, Rilo Kily, Rainer Maria, and many, many other artists through these speakers.

I happily used these speakers for five years or so—even after moving from my hip, urban apartment to the suburban house I live in now—but I eventually tired of the mess their wires made atop and beneath my desk, and moved them into basement storage. Someday I hope to find another use for them, perhaps as a bookshelf system driven by a Raspberry Pi, but I would need to figure out a way to hide all the wires, so the great looks of these speakers shine through.

Altec Lansing Computer Speakers

Over winter break, during my sophomore year in college, I bought my first new computer: a beige Dell tower with an Intel 486 processor. When pricing out systems—and this was done over the phone back then, rather than over the internet, because my parents did not have internet access in 1997—I configured nearly identical systems from Gateway and Dell at the same price. The only difference between them was in the peripherals: the Gateway came with a 19-inch monitor, rather than a 17-inch monitor, and the Dell came with a USB-connected, 2.1 channel Altec Lansing speaker setup. I bought the Dell, to get the better speakers.

At the time, I thought the trade-off was completely worth it. The speakers were tiny, stylish, had some fancy USB connectivity (USB was brand new then!), and came with a subwoofer, which I had never had before. The subwoofer added a new dimension to my music that I had never experienced before. It could shake the room if I wanted that, or just add some sub-bass dimension to the music. Its presence inspired me to pair this speaker set with my old, 2-channel Altec Lansing computer speakers, to create a 4.1 channel setup that I used to watch DVDs in my dorm room in 1999 and 2000. I had to upgrade my sound card to a Sound Blaster Audigy to get that to work. (I think that is the last dedicated sound card I ever bought!)

Their USB connection was not all I had hoped for, however. It did not carry the audio signal; it only allowed you to control the volume and EQ from a Windows menu bar application. It was pretty sophisticated for the time, but it was superfluous, and, I discovered after a year or so, the drivers that made it work caused Windows to crash all the time. So I disabled the USB feature and continued to use them for about 10 years, through college, grad school, and beyond. Eventually they wore out so badly they could no longer play at a proper volume. By that point, though, I had moved onto using an iPod for most of my music playback.

My first computer speakers

I got my first computer when I was in seventh grade. It was an IBM AT/XT that we upgraded several times over the years. By the time I was in high school, my dad bought me a SoundBlaster sound card and some 6-inch computer speakers. I actually do not remember who made them: it was either JBL, Creative, or Altec Lansing. What I do remember is that they were the generic beige color of all PC hardware of the era, the right speaker had knobs for balance and volume, and, as a pair, they could go very, very loud. No one else I came across had computer speakers that large or that loud.

Sound quality-wise, however, they were not great. Back then, in the late 1980s and early 1990s, it was still rare to hear any sounds at all coming out of a computer. It was enough to be able to hear the beeps and blips coming from my DOS-based productivity software and games.

Due to lackluster sound quality, and the fact that CD-ROM drives were too expensive for me to buy until the mid 1990s, these computer speakers never replaced my CD system’s speakers as my main playback system. They are important to me, however, because they enabled me, for the first time, to use the computer to record and mix music.

Sony CFD-510 Boombox

A week before I left for college I bought a Sony boombox to use as a bookshelf stereo. It had detachable speakers, so you could actually achieve stereo separation, and, of course, “mega bass”, which was pretty much mandatory for good sound in such small speakers.

I chose this particular model because it had an analog 3-band equalizer, as opposed to several genre-specific settings; I relied on the EQ to pick out guitar and bass parts I would transcribe. As a bonus, it didn’t have a crazy light show like the many of the other boomboxes on sale in 1996.

I don’t remember very well how it sounded, to be honest, because I wasn’t able to use it that much. My freshman year roommate and I did not share musical tastes, so I had to play my music through my computer using headphones. (My computer’s CD-ROM drive actually had a dedicated “play” button and its own headphone jack.) I didn’t realize it at the time, but all those hours listening to music over headphones (the cheapest headphones possible, I’d say) in my dorm room were the very beginning of my headphone-centric music listening preferences.

My first speaker system

My parents bought me my first CD player at the JC Penney Outlet. It was a damaged, open-box, no-name system that resembled a single, tall unit. It contained, from top to bottom, a turntable (though the clear cover was broken off and missing), an AM/FM radio, a five band equalizer, a dual deck cassette, and a single cd player at the bottom. The only reason I asked for it, and thought my family could afford it, was because it was damaged and was being sold at a steep discount. I also told my parents I would listen to classical music on it, which was my intent, but didn’t actually happen too often.

It came with two bookshelf speakers with RCA inputs that plugged in the rear, that I set up about ten feet away from the receiver. I couldn’t tell you how good or bad the sound was. All I knew at the time is that it was amazing compared to what I had at the time: my mom’s 20-year-old transistor radio, and a cheap, toy-like boombox with a dual cassette deck. The most important upgrade, of course, was upgrading from records and tapes to CDs. CDs didn’t have tape hiss, had high dynamic range, and didn’t wear out over time or get eaten by the plater sometimes.

I blasted music through this no-name system for hundreds of hours through middle school and high school. I measured my school papers by how many album listens it took to write them. I used it to practice singing, to transcribe songs with my guitar, to play back 4-track recordings, to lie back on my bed with CD liner notes while my favorite new song played on repeat.

I amassed an enormous CD collection, mostly through the Columbia House and BMG Music clubs, and partly through weekly trips to my local record store (which is long gone now).

Now that I’m a parent, I am amazed that all my loud music playing didn’t drive my parents crazy. They never complained to me about my music blasting from 3 PM to 10 PM every day. My kids are too little to listen to music on their own, but I’m already thinking about which headphones to get them, so we can all coexist in the house.

I have no idea where this system went or who made it, but, based on it being my first CD player, it is probably the most important speaker system I have ever owned.

Speakers over the years

I love music, and I love headphones, but, oddly enough, I have no special love for speakers. The reason, I suppose, is that, since I was a broke teenager living with my parents, I have never had the opportunity to listen to loud, room-filling music at my home. Roommates, sleeping children, and close neighbors have always prevented it. That said, my love of music has always depended on speakers, and, as I got older, they got a little better over the years.

I’m going to publish a short series of posts about the various speaker systems I’ve had over the years. After that, I will post a short series of posts about all the headphones I’ve had, and loved, over the years, as well.

SwiftoDo Development Notes, July 2018

I took a break from SwiftoDo development to build a new app, Simple Call Blocker, which I posted about earlier this week. Building it was a fun diversion, and I learned a lot in the process, too. If you’re reading this, you’re probably wondering what’s up with SwiftoDo, however. I have been working on it this summer, too.

Since this spring, I have been promising everyone that I’m working on iOS 11+ Files app integration. This feature will let SwiftoDo open files from any cloud service provider that ties into the iOS 11+ Files app. That includes Dropbox, Box, NextCloud, OneDrive, Google Drive, and many others. Adding additional data providers to SwiftoDo has been a long time coming.

Some background on SwiftoDo data providers

I designed SwiftoDo data providers to be plugins that could be swapped out, which would allow me to support numerous cloud storage providers. I have had so much trouble getting the Dropbox data provider to be solid and stable, however, that I was loath to create more data providers. My thinking was that I was liable to cause more problems for my users (and myself!) than I would solve. Therefore, I concentrated on fixing up the Dropbox data provider code, which is now, after three or four rewrites, pretty solid.

(The Dropbox data provider code has always worked, but it had a rare but nasty crashing bug for some time, and some issues related to stability, ability to handle spotty network connections, and ability to handle, gracefully, Dropbox “rate limit exceeded” API responses.)

iOS 11’s Files app, which I did not anticipate being available when I first wrote SwiftoDo, obviates the need for additional “native” data providers. I just wasn’t sure if SwiftoDo would be able to tie into it.

Can Files integration be used for SwiftoDo?

I have been under the impression that integrating with the Files app would require a rewrite of major sections of the app, or would simply not work well due to sandboxing limitations. I thought this because all Files-based iOS apps that I have used follow Apple’s “Document-based app” template very closely: Think “Microsoft Word” rather than “Reminders” in terms of user interaction patterns. They open to a file browser, you open a document (typically a single document), work on the document, save it (automatically), and close the app. The life cycle of a document is fairly limited: after the app is killed, your file is closed and does not reopen on load. Most of these apps don’t work offline at all, unless you’re working with local-only files, because they can’t open your file.

In contrast, SwiftoDo works a lot differently. It manages your task list locally and syncs it to an external file. It lets you archive completed tasks to a second external file. It keeps the opening and choosing of files down to a minimum. Most users set up their todo.txt and archive files once and never touch those settings again. It lets you work offline (primarily in “manual sync mode”, but also when the network is unavailable) and sync your changes to the cloud on demand.

Integrating SwiftoDo with the Files app, without giving up anything, seemed like it might be a considerable challenge.

A “Files” data provider

To my surprise, implementing a “Files” data provider has not been as challenging as I thought it would be. Accessing documents via the iOS document picker and restoring them after the app is killed, via secure bookmarks, is actually pretty easy. It took me only a couple hours to set up a data provider that would upload and download to iCloud Drive and even Dropbox through the Files app.

That is not nearly enough to ship the feature, though. There are still some issues regarding stability and error handling that I have to work through.

Adding this feature also prompted me to display file names in Settings (rather than 2 screens deep in Settings) and atop the task list in the main view.

What is next?

After I finish the Files data provider work, and the new Xcode and iOS versions are officially released, I plan to build SwiftoDo on the iOS 12 SDK and drop iOS 10 support. I’ve been thinking of bumping the version number to 3.0 at that point, to mark the change in iOS compatibility.

I will also consider the future of Files integration in SwiftoDo. It temping for me to remove the entire “data provider” layer and just make SwiftoDo a normal iOS document-based app. That would be a big deal, and I would not make that change unless I understood fully what that would mean for users. I also have to consider how long I will continue to support the existing Dropbox data provider, as it will be somewhat redundant.

After that, I will have the opportunity to simplify the codebase quite a bit. It is tempting for me to rewrite some or all of the UI layer, to incorporate the new techniques I have learned since coding version 2, over a year ago. Any changes to the UI code will probably be related to new features or a minor redesign of the sorting/filtering interface that I have been thinking about.

Introducing: Simple Call Blocker

Recently I released a new iOS app: Simple Call Blocker.

It is a free utility that lets you block unwanted calls to your iPhone. Unlike most of the call blockers on iOS, it allows you to block whole ranges of numbers, such as your phone number’s extension, for free. You may also whitelist numbers, ranges of numbers, or all your contacts’ phone numbers, so that they will not be blocked by this app, even if they are in the blacklist.

The Simple Call Blocker website explains it in more detail.

Why did I write it?

I wanted to write a small, relatively simple app that would allow me to explore the following things:

  1. iOS application architecture: I have been reading books and articles on iOS application architecture, and decided to create a new app to practice new techniques, such as the use of coordinators for navigation rather than storyboard segues, that I have been learning.
  2. algorithms and operation queues: I started the app by writing some simple algorithms for creating sequential phone number ranges to load into an iOS CallKit directory extension. The last thing I wrote was a multi-threaded operation queue for processing blacklist and whitelist rules and refreshing the iOS call directory extension that actually blocks the phone numbers.
  3. Core Data: I avoided learning Core Data for years; that changed with this app.

Overall, the app was a lot of fun to write. It took me about a month in my after-hours “free time” to create. The overall process has made me a better iOS app developer. I’m excited to bring forward the skills and concepts I developed on this project to future work.

Why a call blocker app?

I started getting neighbor spam calls, so I downloaded nearly all the iOS call blocking apps I could find. There were fewer such apps than I thought there would be, all of them seemed amateurish in some way or another, and all of them (as of a month ago) required an in-app purchase or a subscription to block my neighborhood exchange. I wasn’t willing to pay for that feature in any of the apps that I tried, because all of those apps weren’t that good. Plus, blocking an exchange, or a continuous range of numbers, is pretty trivial, so I thought I could create an app that did that, and offer it for free to people.

So is this just a “practice” app?

No. It is well-written and works as well as iOS’s Call Directory extensions allow it to. It has a rough edge or two, though, in that it reloads its directory extension and reports success or errors back to the users, rather than trying to prevent the user from ever encountering an error from being reported by the directory extension loading process.

What that means is that you can ask Simple Call Blocker to block more numbers that iOS will allow—there is an undocumented limit—and the app has to wait for the CallKit Directory Extension’s load process to report success or failure before it can tell the user what is going on. I decided not to try to impose limits on how many numbers could be blacklisted, but instead allow the app to report the Directory Extension’s errors, if any, back to the user. I figure that the undocumented maximum number of blocked phone numbers probably is dependent on whatever hardware is in your phone, and probably is increasing in every new iPhone model.

The Simple Call Blocker directory extension is coded extremely conservatively, and it optimized for very low RAM and system usage. If iOS cannot load it, it is because the user put too many numbers in the blacklist, or because it is still loading numbers from a prior attempt.

Releasing the app for free, I think, makes it OK that it may not work exactly as users expect it to.

What is the future of this app?

I plan to support it through various iOS releases, but otherwise not improve it too much. After all, it is a free app.

I want to know more!

Go ahead and download the app in the iOS App Store (it’s free!), and check out the FAQ online.

On Internet Trolls

DON’T FEED THE TROLLS, AND OTHER HIDEOUS LIES” is a great article by “Film Crit Hulk” on our collective failure to respond properly to internet trolling culture.

A Twitter follower reminded me of a line in the famous parable from Bion of Borysthenes: “Boys throw stones at frogs in fun, but the frogs do not die in fun, but in earnest.” Defenders of trolling insist it’s all just a joke, but if trolling is inherently designed to get a rise out of someone, then that’s what it really is. In many cases, it is designed to look and feel indistinguishable from a genuine attack. Whether you believe what you are saying or not is often immaterial because the impact is the same — and you are responsible for it, regardless of how funny you think it is.

I think that there is a fundamental misunderstanding of trolling. It isn’t a joke. It isn’t done for the lulz. “It’s just a joke” is an obvious cover for bad behavior.

It reminds me of an episode from my youth. In high school I had a friend who had a stash of Playboy magazines that he got (I think) from an older brother. Somehow we found out about them, demanded to see them, and teased him about them as we thumbed through them together. “Why do you have these” we would ask, teasingly, knowing full well why he had them. My friend’s face would grow bright red and we would stammer: “because they’re so funny”. When pressed, he would double down on it: he would swear, up and down, that he had them because they were hilarious. Sure they were.

It puzzles me, why we act as if it’s even possible that verbal abuse on the internet is “just a joke”. A decent response to “it was just a joke” is “it doesn’t matter”.

The biggest mistake we ever made with trolls was making the question of abuse about how to placate and fix them instead of how to empower the people they hurt or manage your own well-being in the face of them. Like so many abused people, we thought the solutions involved walking on eggshells and not provoking them back. But instead, we must acknowledge “that we are what we pretend to be, so we must be careful about who we pretend to be.” And that means acknowledging the awful, terrifying power of jokes and the immunity we seek in “not being serious.” This is exactly why people troll in the first place. Because deep down, they know it’s serious, and that’s exactly why it makes them feel powerful.

In the online world, people who violate community standards should be banned from those communities. Gathering spaces online are not public spaces: almost all of them are owned by private companies or individuals. Freedom of speech is up to the owner of the space; the level of discourse there directly reflect’s the owner as well. By law, they might not be legally responsible for the content of their site, but they are ethically and morally responsible for it, regardless. Owning and running a site where terrible things happen should be a black mark on a company’s or a person’s reputation—and that should matter.

It would be nice if people started to care about reputation again, and if bad reputations led to lower profits and lower stature in the global community. Sadly, we are in a time, right now, where that does not seem to be the case.

Re-committing to Pinboard, after many months away

I’m re-committing to Pinboard, after a year or more away from it. I’m happy with what I am doing now, and thought I would document it in case anyone else wanted help understanding how to use the Pinboard effectively, especially if their usage lapsed, as mine did.

What is Pinboard?

Pinboard is an “antisocial” cloud bookmarking service. You can keep all your bookmarks there and use its barebones website or third party apps and browser extensions, all using an open API, to access them. It’s a paid service, run by a single person, with a clear and straightforward business model. When I signed up, I pre-paid for ten years of service. Part of my impetus for using it again now, after having abandoned it for, well, nothing, is the sunk-cost fallacy. The other, more important part of that impetus is that I really like the simplicity and speed of Pinboard, and I like the Pinboard iOS client I use, Pinner.

What do I use it for?

I use it for three things:

  1. To host my bookmarks in a cross-platform, always accessible way. I can get to the same bookmarks in Safari on my Mac and iOS, and in Chrome on Windows.
  2. For research and archival purposes, especially for programming projects I am working on. I can search these bookmarks on keywords, title, or description to review the best of the web pages I previously read on a topic of interest.
  3. As part of a homegrown “read it later” service. I can send article URLs to Pinboard from various apps, and read them later using Pinboard’s website, an app or browser extension on my Mac, and an app on iOS or Andriod.

Number 3 used to be the primary purpose of Pinboard to me. I had signed up as part of an effort to get replace Pocket with something more privacy focused. After many years of using Pocket (formerly “Read It Later”) to collect articles I was interested in from the huge stream of RSS feeds I parsed every day, I wanted a change. Primarily, this was because I became uncomfortable with Pocket’s business model: Why was it free? How did they really make money? What were they doing will all the data they collected on me?

I also wasn’t crazy about some of the UI changes made to Pocket over the years. I wanted more control over the reading experience, too, which is something that using a web service with an open API would give me. It helps that, at the time, Safari’s Reader View debuted, and I thought it was fantastic.

I was pretty obsessive about channeling all the articles I read through Pinboard, so I had a one-way workflow from discovery to reading to marking read. I never deleted anything from Pinboard, either. I thought I wanted a history of all the articles I ever read, in case I wanted to search through that history later. (Of course, I never did that.)

Why did I stop using it?

I stopped using Pinboard for three main reasons:

  1. I started reading Twitter more than actual articles linked to from it. The constantly updating timeline was incredibly addictive, and less mentally taxing to follow than reading complex articles from actual publications. (I have since given up Twitter because it was too addictive for me to handle responsibly.)
  2. My wife and I had kids, meaning that I no longer had a bunch of downtime after dinner to catch up on all the articles I had bookmarked to read later. I would still send stuff to Pinboard to read later, but I would never actually read the articles.
  3. My wife and I subscribed to The New Yorker, The New York Times, and The Washington Post. I started reading from those publications, from their apps, a lot more than scouring RSS feeds for articles from a dozen sources. Reading from their apps did not fit very well with my Pinboard workflow.

Overall, Pinboard became a graveyard for links I didn’t actually want to read. Instead of a useful resource, it was a junk pile full of stale content.

Digging out of a mess

I took the following steps to return Pinboard to a useful utility for me:

  1. I deleted everything I had in Pinboard—over 3,000 bookmarks that were doing me no good. Most of these were articles I imported from my RSS reader (Reeder) or Twitter (via Tweetbot), read once, and then just left in Pinboard.
  • I installed Shiori on my MacBook Pro. Shiori is a Pinboard bookmark launcher and editor. It’s like QuickSilver for Pinboard—hidden until you need it, only a keypress away, and accessible from anywhere. I set it up so that Control+Option+Command+P brings up the bookmark search window (from anywhere), and Control+Option+Command+B brings up the bookmark editor.
  • I set up Pinner on iOS. Pinner is a full-featured Pinboard client. It will open Pinboard bookmarks in Safari or within Pinner, via Safari View Controller. It has two app extensions for creating bookmarks. The first extension, “Quick Pin”, has no UI, and is for quickly adding bookmarks to read later. The second extension lets you edit, interactively, all the metadata associated with the bookmark prior to saving it.

My workflow

I developed a new workflow to work with Pinboard, so I don’t end up with a mess of useless bookmarks again. Honestly, though, calling it a workflow is an exaggeration. I basically decided to manage Pinboard with a simple set of rules.

I will continue to use Pinboard both for permanent bookmarks, which mostly involve specific technical documentation about Swift and iOS development, and for a read-it-later service, which are bookmarks I want to keep around temporarily, some of which I plan to keep long term.

  1. Bookmarks I would keep in Safari, for sites I would log into (banking websites, personal websites, blogs, GitHub, BitBucket, etc.), are stored as private bookmarks with tags. All of these bookmarks are also tagged “Safari” so I can pull them all, as a group, with a Pinboard search.
  2. Bookmarks for articles to read later, and everything else, are saved with the “read later” flag set to “true”, primarily by using Pinner’s “Quick Pin” extension or the “send to Pinboard” command within Reeder (my RSS reader app of choice).
  3. I regularly use Pinner or Shiori to browse my “read later” list. Basically, I had to kick the Twitter habit.
  4. After I read articles marked “read later”, I delete the bookmark, or choose to save it. I am pretty ruthless about deleting bookmarks now, which is the opposite of how I used to be. If I don’t read something after a few days, I will just delete it.
  5. Rarely, I will choose to save the bookmark. If I do so, I edit the bookmark’s metadata to remove the “read later” flag and to add keywords and a description. I open copy the first paragraph of the article to the bookmark’s description field, so it’s clear to me later on why I saved it.

So far this workflow has been working well for me. I collect “read later” bookmarks throughout the day, read through them in the evening, and delete almost all of them at the end of the day. My Pinboard bookmarks list is much smaller than before, but contains only good stuff that I want to act on, either now or later.