Press "Enter" to skip to content

Russell Finn’s Blog Posts

Apple and Twitter update

I was gratified to see this report (the day after I wrote my letter) that Apple is indeed “pausing” their advertising on Twitter. (I don’t take any credit for this.)

I can only hope that they don’t see fit to “resume” any time soon, given the present circumstances.

Comments closed

Apple and Twitter

This evening, I sent the following email message to Tim Cook at Apple:

Dear Mr. Cook:

I have been an Apple user since 1981 and a Mac user since 1984; my first iPhone was an iPhone 4, but mostly because AT&T didn’t have good coverage in my home town. As I sit at my desk composing this email, there are eight Apple computing devices literally within arm’s reach, not to mention a couple of HomePods and a pair of AirPods.

Professionally, I wrote my first Mac program in 1984 (for a company mentioned in the first issue of Macworld magazine), and my first publicly released Mac software in 1987. My career path wandered a bit after that, but I have been developing Mac software for pay since 2006 and it has been my full-time job since 2009.

I write all this to establish some bona fides for my long relationship with, admiration of, and support for Apple Inc.

Like many people, I was driven to leave Twitter soon after its change of ownership, disturbed at first by the way he treated his employees and third-party developers, and afterwards by the increasing amount of hate speech and abhorrent messages being posted there, apparently not merely tolerated but encouraged by the new owner.

I have been somewhat dismayed that Apple continues to market itself there, but I am not naive, and I recognize that the goals of a major company are quite different from those of a private individual, and that it is necessary for a company to engage with potential customers on a variety of media.

But now I find myself driven to write this letter in response to news items from the last few days:

… to mention only a few.

I cannot believe that it continues to be in Apple’s best interest to have its valuable brand appear adjacent to such virulent, hateful content. Apparently, the leadership at IBM has reached a similar conclusion. I hope that you and the leadership team at Apple are already giving careful consideration to the effect of continuing to financially support such a platform.

At the top of Apple’s “Ethics and Compliance” page, above your name, is the statement: “We do the right thing, even when it’s not easy.”

I urge you to do the right thing.


Russell Finn

Comments closed

Did you miss me?

Well, I’ve finally managed to get my blog up and running again. It appears to have been offline since August of 2021 — at least, that was when the last automated backup arrived in my WPBackups mail folder. To be honest, my shouting-into-the-void needs had largely been met by Twitter (at least until last November), so I wasn’t in much of a hurry to investigate. But it seemed to make sense to self-verify my Mastodon profile, which meant getting this website back online. I took the opportunity to update my Linode instance from Ubuntu 2016.4 LTS to something newer, install the latest WordPress, etc.

It turns out that the plugin I had been using to get those regular backup emails was only sending me the contents of the database as a SQL file, whereas most of the online guides to “restoring” or “migrating” a WordPress site assume you have an XML-based export file. After a couple of false starts, I found this article which had the key to success: namely to create a new database and populate it from the SQL file, then install WordPress and point it at that database during the “five-minute install” process. At this point WordPress will say “You appear to have already installed WordPress; let me just bring your database up to date” and then you’re ready to go, more or less.

(I got an immediate error that included the name of the theme I had forgotten I was using. Reinstalling that was much more pleasant than trying to get something I liked out of the default WP themes that are based around the WP block editor, which seems like overkill for a simple text blog.)

Now that I’ve done all that, will I begin blogging regularly again? We’ll see; if so, it will likely be more articles on macOS and Swift programming, and fewer hot takes on hot button issues (which frankly I don’t have the energy to deal with these days).


A pox on everyone’s house

This story appears to solely take Epic’s word about Apple’s response to Epic’s recent actions (and the headline is even worse).  I see no evidence that Apple was asked for a comment, although of course they probably wouldn’t have given one.

Given that Epic has intentionally and flagrantly violated Apple’s terms and conditions, it is not surprising that Apple would be considering revoking Epic’s developer account; they’ve done this before, and with less notice. But it’s hard to agree with framing this as “retaliation” rather than enforcing a contract.

Epic’s actions of deliberately poking the bear, and then crying foul when the bear swats them down, reminds me of the classic definition of “chutzpah”: killing your parents and then throwing yourself on the mercy of the court on the grounds that you’re an orphan. It’s clear that Epic is trying to game the situation by playing things out in the court of public opinion as much as possible. As an Apple developer, I believe that certainly Apple can (and should) do much better by their developers—but Epic’s antics are unlikely to gain them much sympathy among developers, either.

Comments closed

New opportunity arriving on track 1

I’ll be starting a new job within a couple of weeks. I was fortunate enough to find another remote Mac development position, which I’m very happy about.

I appreciate the efforts of everyone that helped me out along the way (including my family for their support). At least that’s one good thing that’s happened during this annus horribilis

Comments closed

Open to new opportunities

I find myself available for a full-time position as a software developer, preferably on Apple platforms (macOS, iOS, etc.) using Swift or Objective-C. I prefer a remote position but will consider opportunities in the Baltimore-Washington region (when offices reopen, of course). View the “Résumé” page (linked above) for links to my current résumé, my LinkedIn profile, etc.

Comments closed

NSFileHandle permission errors

In a macOS programming project I have a command that allows the user to open a file containing some configuration options. This file is a property list, so the contents were being read using NSDictionary(contentsOf:); this method simply returns nil if an error occurs. I wanted to provide more details about the failure than simply “The file could not be read”, so I looked for a Foundation method that would throw an NSError. I settled on FileHandle(forReadingFrom:) and inserted the following code:

    do {
        _ = try FileHandle(forReadingFrom: url)
    catch let error as NSError {
        let alert = NSAlert()
        alert.messageText = "An error occurred while reading the options file.".localized()
        alert.informativeText = error.localizedDescription
        alert.beginSheetModal(for: mainWindow) { (response) in
            if response == NSAlertSecondButtonReturn {
                OperationQueue.main.addOperation { self.resetOptions(nil) }

Then I set up a few test cases, including a file that was owned by another user (with no read permission). To my surprise, the error description implied that I was unable to write the file:

[application icon redacted]

…and while that’s also true, that’s certainly not the error I expected to get.

I looked at the error object in the debugger, and sure enough, the error code was 513 (NSFileWriteNoPermissionError) and not 257 (NSFileReadNoPermissionError). Weird.

Well, I know I’m trying to read the file, and I don’t want to confuse the user, so I changed the catch clause to handle this case:

    catch var error as NSError {
        if error.code == NSFileWriteNoPermissionError {
            error = NSError(domain: NSCocoaErrorDomain, code: NSFileReadNoPermissionError, userInfo: error.userInfo)
        let alert = NSAlert()

…and that seemed to do nicely. But I can’t find any documentation on whether this is expected behavior or what I might be doing wrong.

Comments closed

Annoying new telemarketing tactic

Twice within the last week I’ve been hit by the following tactic:

I receive a call on my cell phone from a nearby calling area (Baltimore, in my case).  The middle-aged voice on the other end asks for “Mason” (or “Terence”). When I politely reply that there’s no one here by that name, the person responds “Oh, perhaps you can help me”, and launches into a solicitation for some high-minded charitable donation.

Last week I simply told the gentleman that I couldn’t help him and hung up.  Today, interrupted from a particularly knotty work issue, I pointedly asked the woman if this was a new marketing tactic and could I expect similar calls in the future. She simply said “I’ll update our records” and hung up.

Will no one rid me of these troublesome callers?

(I’d installed Nomorobo on my iPhone—it’s apparently the best of the current bunch of call blockers—but obviously technology has its limits. Also, for some reason Nomorobo had managed to disable itself and I had to go back into Settings to re-enable it.)

Comments closed

AppKit bug in 10.12.2: NSTextField with tabs in text displays incorrectly

UPDATE: The bug described below is fixed in macOS 10.12.4 and the workaround described is no longer necessary (except for backward compatibility).

In a recent macOS project I have an NSTextField that contains text with tab characters in order to display a data table. (The text is an NSAttributedString to which I apply an NSParagraphStyle with its tabStops property set to an array containing a number of right-aligned NSTextTabs.)

The text field was drawn as intended (with the text aligned to the tab stops) before upgrading to 10.12.2. After upgraded, the text was no longer aligned to the tab stops, and when using monospacedDigitSystemFont there were cosmetic glitches displayed as well:

Under time pressure for a release, I implemented the workaround of replacing the NSTextField with an NSTextView. (I did this dynamically since it is not obvious how to create “bare” NSTextViews in Xcode’s Interface Builder.) Using an NSTextView I was able to get the data table to display as I had intended.

When writing up this bug (#29758498; Radar, Open Radar) I tried to create a simple test case that would illustrate the issue, but on my first try to recreate the problem from scratch, the issue didn’t appear. Puzzled, I copied the code and .xib file from my application into the test project, and was able to reproduce the issue.

By examining the text of the .xib files, I discovered that my newly created .xib file has a content view with wantsLayer=”YES”, and in this case the NSTextField works as intended under 10.12.2; but the .xib file from my application (which was created before Xcode 8 was released) did not have a layer set on the content view, and this did not work under 10.12.2 (although it had worked fine on 10.12.1 and earlier). Setting a layer on the application’s window’s content view (in the View Effects tab of the Assistant Editor in Xcode) was enough to fix the issue and make the table display as intended:

(Yes, bridge players, those point counts are bogus; my test program is generating random values to insert into the table.)

My wider questions are:

  1. What happened? We know there were a lot of graphic updates in 10.12.2, but it’s odd that the problem only occurs with the system font. I haven’t investigated whether the font file itself has changed.
  2. I can’t believe I’m the only person that’s run into this (although my usual googling produced no other hits). Is this really an uncommon case? Or is this a(nother) gap in Apple’s test suite?
  3. If Apple is expecting that the default case for content views is to have wantsLayer set, then it should certainly make this more widely known. I couldn’t find any references to this issue in the AppKit release notes.

Reading text files with arbitrary line endings in Swift 3

It’s easy enough in Swift to get an array of strings representing the lines of a text file:

  let contents = try! String(contentsOf: textFileURL)
  let lines = contents.components(separatedBy: .newlines)

…but what if the input might be a DOS format text file? CharacterSet.newlines contains both "\r" and "\n", so the code above will divide the text at each of them, and the array of strings will contain an extra empty string between every line.

Turns Out™ that Foundation has a number of APIs that understand all the ways line endings are represented in text files. The easiest way to read a text file with arbitrary line endings is to use the enumerateSubstrings(in:options:body:) method, specifying EnumerationOptions.byLines. This uses getLineStart(_:end:contentsEnd:for:) to recognize the line endings (see the documentation thereof for details) and is powerful enough to handle files with mixed line endings.

(In Objective-C these are the -enumerateSubstringsInRange:options:usingBlock: and -getLineStart:end:contentsEnd:forRange: methods of NSString.)

It’s straightforward to wrap this into an extension on String:

extension String {
func separatedIntoLines() -> [String] {
var lines: [String] = []
let wholeString = self.startIndex..<self.endIndex
self.enumerateSubstrings(in: wholeString, options: .byLines) {
(substring, range, enclosingRange, stopPointer) in
if let line = substring {
return lines

The name separatedIntoLines() seems like the best choice to describe the work being done; the alternative of a computed property simply called lines seems a little too terse to me. UPDATE 2018-02-13: After reviewing the Swift 4 API, perhaps splitIntoLines() would be a better name.

Comments closed