Archive for June 29, 2017

Thursday, June 29, 2017

My 2017 iMac

The Mac Pro is still an unavailable unknown, and the iMac Pro is not really what I was looking for, so I upgraded my 2012 MacBook Pro to a 2017 iMac (27-inch, 4.2 GHz i7).

I got the version with a built-in VESA mount. I’m mounting it on an UPLIFT View Monitor Arm, which is rated for up to 19.8 lbs. The non-VESA iMac is listed at 20.8 lbs., and Apple wasn’t able to tell me the weight without the stand, but this combination seems to work fine after I turned the weight adjustment all the way. If I were buying again, I might try to find an arm that has a little bit more range of vertical motion.

It’s been a long time since I upgraded RAM in a Mac, since my last several Macs were either not upgradeable or I maxed them out from the start. This time, the iMac supports up to 64 GB. I bought it with 8 GB and added 32 GB, savings lots of money and ending up with more RAM than if I’d bought it from Apple. The door and levers were incredibly easy to use, probably the smoothest Mac RAM upgrade I’ve ever done.

This is my first Mac without Apple Hardware Test, and unfortunately the new Apple Diagnostics does not test RAM. I installed Memtest and ran it single-user mode. I seem to remember this taking a very long time with older Macs, but even with 40 GB of RAM it completed overnight.

The iMac’s display is incredible. My original plan was to keep the 30-inch Dell display that I used with the MacBook Pro as my main display, using the iMac on the left side as I did with the MacBook Pro. I thought I would miss the extra vertical space since the iMac’s 27-inch display is only 1,440 vs. 1,600 points high without scaling. However, the Retina text is so sharp and the colors are so nice that I ended up putting the Dell off to the side. I’ve found plenty of uses for all this screen space, but unfortunately the Mac sometimes fails to wake the external display, which reports that it isn’t getting any signal, even though the Mac still acts like there is a display attached. Resetting the PRAM and various other remedies haven’t helped. I have to power cycle the display to get it recognized, and then rearrange my windows (with the assistance of Moom).

I’m very happy to have Ethernet again. Technically, I could have used it with my MacBook Pro, but I didn’t have enough Thunderbolt ports to use the adapter and never bought a dock. Aside from Ethernet preventing the occasional problem with Wi-Fi disconnecting or joining the wrong network, network transfers are much faster than before, even though the other Macs I’m connecting to are using Wi-Fi.

Between the faster processor and SSD, everything feels faster. Building SpamSieve takes 1m15s (while the iMac was doing some Spotlight stuff and FileVault encryption in the background) vs. 1m54s on the MacBook Pro. Lightroom is also much faster at importing photos and building previews. Unfortunately for a desktop computer, the iMac seems just as prone to turning on its fans as the MacBook Pro. It’s fast, but just opening up Xcode makes it sound like it’s really working hard. And there is the aforementioned Kaby Lake hyper-threading bug.

I’ve long wanted more performance than a notebook could offer, but I resisted getting a desktop Mac because I didn’t want to deal with file syncing. However, over the years the software situation has improved. My code and text snippets are already in Git. My bug tracker and customer support database are online in FogBugz. My e-mail is in IMAP, and I can remotely train SpamSieve on the iMac from other devices. OmniFocus and Fantastical sync. My RSS feeds and passwords sync. Other key files are in Git repositories, Dropbox, or Resilio Sync. For the remaining documents, preferences, and app data (e.g. MarsEdit), I set up some scripts using rsync.

The iMac came with a Magic Mouse 2, which I expected not to use. I’ve always found its sharp edges uncomfortable when using other people’s Macs, and I would constantly be swiping by accident. However, I was having problems with my Logitech mouse not tracking well unless the batteries were very freshly charged, so I decided to give the Magic Mouse a solid try. I found that if I hold it differently, gripping the underneath sides between my thumb and fourth finger, it works much better. As my hand is no longer resting on top, I no longer really touch the sharp edge at all. I’m not sure yet whether I prefer swipe-scrolling to using a scroll wheel, but I like being able to swipe between pages and spaces. Another pleasant surprise is that the Magic Mouse works fine with my lotion gloves, whereas Apple’s trackpads and iOS devices don’t.

There are two problems with the Magic Mouse. The first is that the Mac often doesn’t recognize it at boot time—even after power cycling it, even though my Bluetooth keyboard works fine. So I have to use the arrow key on the keyboard to select my user for FileVault login, and there’s no way to click the Restart or Shut Down button.

The second problem is that it’s subject to the same spontaneous Bluetooth disconnects as all the Bluetooth keyboards I’ve use with Sierra. But, unlike the Magic Keyboard, the Magic Mouse cannot be used in wired mode because the Lightning connector is on the bottom.

Banning Force Unwrapping Swift Optionals

Alexandre Colucci:

Download a random Sample Code from Apple Developer website and look if and how force unwrapping is used.

[…]

Xcode’s Fix-it feature proposes to insert the explicit unwrap operator… even when it doesn’t make sense[…]

[…]

There are multiple solutions that are cleaner and safer than using an explicit unwrap. I also generally find the code more readable. Below are several examples.

[…]

Similarly to force unwrapping an optional, I see a lot of code dangerously using implicit unwrapped optionals. This kind of optionals should also be avoided… except in one case where it is extremely useful: When declaring an IBOutlet, you should use an implicit unwrapped optional because once the method viewDidLoad is called, the IBOutlet will be initialized.

Another case where IUOs are unfortunately needed is in test code, because the variables aren’t initialized until set setUp() method.

Type-Safe HTML in Swift

Brandon Williams:

An alternative approach to views is using “embedded domain specific languages” (EDSLs). In this approach we use an existing programming language (e.g. Swift), to build a system of types and functions that models the structure of the domain we are modeling (e.g. HTML).

[…]

We can use the type system to provide safety around how plain text is encoded for use with HTML. It allows us to prove that non-encoded strings never make it into our HTML.

[…]

Once you go down the road to thinking of views as functions (Data) -> [Node], you start to build up lots of lil helper views that can be reused in (hopefully) any which way. However, you soon find out that the data these subviews demand needs to be threaded all the way through the view hierarchy all the way back to the root view. This naturally leads one to something known as a Reader and solves this problem in a beautiful way.

Brandon Williams:

In our previous article we described how to build an EDSL to model HTML in Swift. Here we describe how to take our Node value type and render it to a string that can actually be served to the browser.

Brandon Williams:

Now we are going to tackle a problem that goes up one layer in the web-server request lifecycle: creating views. These are the things responsible for taking some data, say a list of articles, and creating the HTML to represent that data. It may sound easy, but there are a lot of difficult problems to solve with views. We want our views to be composable so that we can create small sub-views focused on rendering one piece of data and be able to reuse it. We also want our views to be flexible enough for future developments that are hard to see right now.

A Day Without JavaScript

Sonniesedge (via Hacker News, John Gruber):

So how was it? Well, with just a few minutes of sans-javascript life under my belt, my first impression was “Holy shit, things are fast without javascript”. There’s no ads. There’s no video loading at random times. There’s no sudden interrupts by “DO YOU WANT TO FUCKING SUBSCRIBE?” modals.

If this were the only manifestation of turning off javascript, I’d do this for the rest of time. However, a lot of things don’t work. Navigation is the most common failure mode. Hamburger menus fail to internally link to a nav section (come on, that’s an easy one kids). Forms die when javascript is taken away (point the form to an endpoint that accepts GET/POST queries ffs). Above the fold images fail to load (you do know they’re streaming by default, yes?).