The personal blog of Stuart Breckenridge

On USB-C and Thunderbolt 3  

Marco Arment (via Michael Tsai):

While a wide variety of USB-C dongles are available, most use the same handful of unreliable, mediocre chips inside. Some USB-A dongles make Wi-Fi drop on MacBook Pros. Some USB-A devices don’t work properly when adapted to USB-C, or only work in certain ports. Some devices only work when plugged directly into a laptop’s precious few USB-C ports, rather than any hubs or dongles. And reliable HDMI output seems nearly impossible in practice.

Very few hubs exist to add more USB-C ports, so if you have more than a few peripherals, you can’t just replace all of their cables with USB-C versions. You’ll need a hub that provides multiple USB-A ports instead, and you’ll need to keep your USB-A cables for when you’re plugged into the hub — but also keep USB-C cables or dongles around for everything you might ever need to plug directly into the computer’s ports.

Hubs with additional USB-C ports might pass Thunderbolt through to them, but usually don’t. Sometimes, they add a USB-C port that can only be used for power passthrough. Many hubs with power passthrough have lower wattage limits than a 13-inch or 15-inch laptop needs.

After a bit of trial and error, I’ve settled on using the J5 Create USB-C 4 Port Hub with my MacBook Pro, and I’ve had no issues. Connected to my MacBook Pro:

My current setup just works on my MacBook Pro. (Sans the external SSD, I can also connect the USB-C hub to my (Windows) work laptop and be good to go. Skype for Business calls with an Artemis gaming headset is overkill!) However, it wasn’t all plain sailing.

I initially used Apple’s USB-C Digital AV Multiport Adapter, which had several limitations. Firstly, the USB-C port on the dongle is for power only and doesn’t support data. Secondly, when using the HDMI port to connect to an external monitor, its output was limited to 30fps at 4K1.

I’ve had an equally difficult time purchasing appropriate Thunderbolt 3 cables. The Akitio Node came with a 0.5m Thunderbolt 3 which wasn’t long enough for my needs. My first long cable purchase was the 2m Belkin Thunderbolt 3 cable from Apple. The product description:

This 2-meter cable supports Thunderbolt 3 throughput (up to 40 Gbps), 4K or 5K Thunderbolt display connectivity, and up to 60W of charging power to your Thunderbolt 3 devices.

Use this fully Thunderbolt-certified cable to connect to Thunderbolt 3 docks, hard drives, monitors, and more. You can even use it to daisy-chain up to six Thunderbolt 3 devices.

Unfortunately, it refuses to work with my Akitio Node. Despite being advertised as an active Thunderbolt 3 cable at 2m, it appears to be passive2. I’ve now bought a Cable Matters 2m cable and can confirm that it works perfectly.

Thunderbolt 3 and USB-C are far from perfect. They are, however, a significant step in the right direction.

  1. When using USB-C to USB-C the MacBook will output 60fps at 4K. ↩︎

  2. More info ↩︎


BBEdit 12  

An unexpected release today — BBEdit 12 with over 100 refinements and new features. As usual, they have best in class release notes.

It (still) doesn’t suck and it’s an instant purchase for me.


Easily Steal an iOS User's Password  

iOS asks the user for their iTunes password for many reasons, the most common ones are recently installed iOS operating system updates, or iOS apps that are stuck during installation.

As a result, users are trained to just enter their Apple ID password whenever iOS prompts you to do so. However, those popups are not only shown on the lock screen, and the home screen, but also inside random apps, e.g. when they want to access iCloud, GameCenter or In-App-Purchases.

This could easily be abused by any app, just by showing an UIAlertController, that looks exactly like the system dialog.

Even users who know a lot about technology have a hard time detecting that those alerts are phishing attacks.

Astounding work by Felix Krause which shows just how easy it is to replicate an iOS system dialogue in order to steal a user’s password. Apple must fix this.


Mike Pence Takes Part in Publicity Stunt Instead of Doing His Job  

Kneeling during the U.S. national anthem is a form of protest against racial injustice and to do so is protected under the First Amendment. Thus, when you read this, via the BBC, you can’t help but be confused:

US Vice-President Mike Pence has walked out of a National Football League (NFL) game after several players refused to stand for the US national anthem.

Mr Pence said he could not be present at an event that “disrespects our soldiers, our flag” after abandoning the game in his home state of Indiana.

The Vice President of the United States can’t be present when people excercise their First Amendment rights? It gets worse, though:

The Vice President of the United States can’t be present when people excercise their First Amendment rights because he was taking part in a publicity stunt orchestrated by the President of the United States.

It’s beyond shameful.


AIM to be Discontinued  

Michael Albers:

If you were a 90’s kid, chances are there was a point in time when AOL Instant Messenger (AIM) was a huge part of your life. You likely remember the CD, your first screenname, your carefully curated away messages, and how you organized your buddy lists. Right now you might be reminiscing about how you had to compete for time on the home computer in order to chat with friends outside of school. You might also remember how characters throughout pop culture from “You’ve Got Mail” to “Sex and the City” used AIM to help navigate their relationships. In the late 1990’s, the world had never seen anything like it. And it captivated all of us.

AIM tapped into new digital technologies and ignited a cultural shift, but the way in which we communicate with each other has profoundly changed. As a result we’ve made the decision that we will be discontinuing AIM effective December 15, 2017

The first internet messaging client I ever used was AIM as it was bundled with one of the many AOL CDs. While my friends and I quickly moved to MSN Messenger — which itself was discontinued in 2013 after morphing into Window Live Messenger — throughout school and university, it was AIM that started everything off.

These days I use Skype for Business at work. It holds up OK in a desktop context but it doesn’t translate well as a mobile experience. The way we communicate has, indeed, changed.


Keybase Introduces Encrypted Git  

From the Keybase blog:

It is end-to-end encrypted. It’s hosted, like, say, GitHub, but only you (and teammates) can decrypt any of it. To Keybase, all is but a garbled mess. To you, it’s a regular checkout with no extra steps.

Even your repository names and branch names are encrypted, and thus unreadable by Keybase staff or infiltrators.

We think this is better than paying a fee to store it in plaintext.

I’m no expert, but will encrypting and decrypting larger git repositories not come with a significant performance hit? Regardless, I’m interested in this development and will be testing it out shortly.

(Note: I am one of the people who does sign commits.)


Yahoo Confirms 2013 Data Breach Affected All Accounts  

It turns out Yahoo’s 2013 data breach affected all accounts in existence at the time of the breach:

Subsequent to Yahoo’s acquisition by Verizon, and during integration, the company recently obtained new intelligence and now believes, following an investigation with the assistance of outside forensic experts, that all Yahoo user accounts were affected by the August 2013 theft.

This seemed to be inevitable.

Previously: Yahoo’s 2013 Data Breach Expanded to 2015 and 2016, Yahoo Confirms Security Breach of 1 Billion Accounts


Match Data in GameKit

Over the last few days I’ve started working with the GameKit API for the first time in a few years. It’s as bad as I remember.

The most egregious problem I have come across is this particular API:

GKTurnBasedMatch.loadMatches { (matches, error) in 
    if matches != nil {
	    // Do something with the matches
    }
}

This is the API description:

Loads the turn-based matches involving the local player and creates a match object for each match.

And this is the description of the matches parameter:

An array of GKTurnBased Match objects containing the match objects for matches that the local player is playing in, or nil if there are no matches to load.

This is hardly the full story. The loadMatches API will indeed download matches from Game Center, but what this description lacks is any reference (at all) to the fact that the downloaded matches will very likely include stale or non-existent matchData.1

As I encode the match score within matchData, I ran into issues when Game Center was downloading out-of-date matchData. This necessitated in a second call to either of the following functions before displaying data to the user:

GKTurnBasedMatch.load(withID: match.matchID!, withCompletionHandler: { (match, error) in 
    // Logic
}

Alternatively:

match.loadMatchData(completionHandler: { (data, error) in 
    // Logic
})

In my opinion, the loadMatches API should return the current matches the user is participating in with the latest matchData.

  1. I’ve created rdar://34782360 in the hope that Apple will clear up this description in a future update. ↩︎


Trump Waives Jones Act for Puerto Rico, Easing Hurricane Aid Shipments  

Niraj Chokshi, for The New York Times:

The Trump administration said on Thursday that it would temporarily waive a century-old shipping law for Puerto Rico that officials there said was hindering disaster relief efforts after Hurricane Maria.

The law, known as the Jones Act, was limiting access to food, medicine, clothing and needed supplies, officials said. Sarah Huckabee Sanders, the White House press secretary, announced the waiver on Twitter, saying that President Trump had authorized it after a request from Gov. Ricardo A. Rosselló of Puerto Rico.

This comes after Trump sided with industry as a reason for not waiving the law:

President Trump says he’s reluctant to lift shipping restrictions to get more aid to hurricane-ravaged Puerto Rico — because mariners don’t want him to.

“We’re thinking about that,” Trump said Wednesday when asked about lifting the Jones Act, which prohibits foreign ships from moving goods between US ports.

“But we have a lot of shippers and a lot of people that work in the shipping industry that don’t want the Jones Act lifted, and we have a lot of ships out there right now.”

Industry. Shameful.


Implementing Drag and Drop with an NSManagedObject

Back in July I started adding the drag and drop API to The FFI List. At the time, I wrote:

What I want to do — and what I haven’t worked out yet — is dragging from the search table view on to the saved tab in order to save FFIs. It’ll take a bit more work, but I’m sure it’s doable.

It turns out this was easier than I thought: all I had to do was assign the NSManagedObject to the UIDragItem’s localObject variable (1), add a UIDropInteraction to the appropriate UITabBar subview (2), and make the UITabBarController conform to the UIDropInteractionDelegate protocol (3).

1 — Assign an NSManagedObject to the UIDragItem’s localObject variable:

let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = <#NSManagedObject#>

2 — Add a UIDropInteraction to the tab bar in viewDidLoad():

let dropInteraction = UIDropInteraction(delegate: self)
tabBar.subviews[1].addInteraction(dropInteraction)

3 — Make the UITabBarController conform to the UIDropInteractionDelegate protocol:

func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
    return session.hasItemsConforming(toTypeIdentifiers: [kUTTypePlainText as String])
}
    
func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
    return UIDropProposal(operation: UIDropOperation.move)
}
    
    
func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
    let ffi = session.items[0].localObject as! <#NSManagedObject#>
    // Necessary logic to parse the NSManagedObject
}

You can see it working over on YouTube.