The personal blog of Stuart Breckenridge

Apps of a Feather  

After June 19th, 2018, “streaming services” at Twitter will be removed. This means two things for third-party apps:

  1. Push notifications will no longer arrive
  2. Timelines won’t refresh automatically

If you use an app like Talon, Tweetbot, Tweetings, or Twitterrific, there is no way for its developer to fix these issues.

We are incredibly eager to update our apps. However, despite many requests for clarification and guidance, Twitter has not provided a way for us to recreate the lost functionality. We’ve been waiting for more than a year.

Either Twitter fix this, or I’m off the platform.

Update 2018-04-06:
Stephen Hackett:

If this comes to pass, I think I’ll be on Twitter far less than I am today, and while that may be a good thing for me personally, it’s bad for the developers of these apps, and bad for Twitter itself. The company should fix this.

Manton Reece:

Dieter Bohn:

Juli Clover:

The developers behind Tweetbot, Twitterrific, Talon, and Tweetings are asking customers to contact the @TwitterDev account to correct the situation and to use the #BreakingMyTwitter hashtag to spread awareness.

macOS 10.13.4 eGPU Support  

The 10.13.4 release of macOS includes full support for eGPUs. As detailed in the support note:

With eGPU support in macOS 10.13.4, you can:
• Accelerate applications that use Metal, OpenGL, and OpenCL
• Connect additional external monitors and displays
• Use virtual reality headsets plugged into the eGPU
• Charge your MacBook Pro while using the eGPU
• Use an eGPU with your MacBook Pro while its built-in display is closed
• Connect an eGPU while a user is logged in
• Connect more than one eGPU using the multiple Thunderbolt 3 (USB-C) ports on your Mac
• Use the menu bar item to safely disconnect the eGPU
• View the activity levels of built-in and external GPUs. Open Activity Monitor, then choose Window > GPU History

What you cannot do with a connected eGPU, and which is major disappointment, is accelerate the internal display of an iMac or MacBook.

Encapsulating Table View Row Functions in a Struct

During a recent refactor of a table view data source, I created a struct for table view row data that would encapsulate both UI data and any necessary function to perform when the row is selected. It looks like this:

struct TableViewRowData {
    var title: String
    var performingFunction: (() -> Void)?

Adding a few TableViewRowData entries to an array:

let dataSource: [TableViewRowData] = [
    TableViewRowData(title: "Row 1", performingFunction: {
		print("Row 1")
    TableViewRowData(title: "Row 2", performingFunction: {
		print("Row 2")

Then, in the UITableViewDataSource:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return dataSource.count

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "rowCell", for: indexPath) as? TableViewCell else {
        return UITableViewCell()

    cell.titleLabel.text = dataSource[indexPath.row].title

    return cell

And in the UITableViewDelegate:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)

This approach keeps the UITableViewDataSource and UITableViewDelegate a bit tidier.

Announcing SG Transit  

SG Transit is a simple yet powerful app that gives you up to date arrival times at all bus stops in Singapore. Using your location, the app can determine nearby bus stops, or you can search for any bus stop in Singapore. Not only do you get the estimated arrival time, you can also see the location of arriving buses on the map. Subtle colour changes also let you know whether you’ll be able to grab a seat on an arriving bus.

That’s not all, though! SG Transit also allows you to view the latest MRT service status and any available public bus or MRT shuttle serivces that are in operation. The app also supports English or Chinese station names.

With a clean, modern design, and all of the above features, what are you waiting for?

SG Transit is available for free on the App Store.

Dashlane Love Marketing of Anonymous Information  

Killian Bell, Cult of Mac:

Password management service Dashlane today published its 2018 City Security Rankings, revealing the state of password security in America’s most populous cities — and those that are home to some of the biggest companies and government agencies.

This is covered under their Privacy Policy:

Creation of Anonymous Information. If we have any information that is identifiable with a particular person, we may create Anonymous Information records from such Information by excluding information that makes the information personally identifiable to you. We reserve the right to use Anonymous Information for any purpose and disclose Anonymous Information to third parties. “Anonymous Information” means information that does not, by itself, permit the identification of individual natural persons.

However, three things are worth mentioning:

  1. Why are Dashlane collecting password strength data of their users? (Hint: marketing.)
  2. Why are they sharing it? (Hint: marketing.)
  3. Use 1Password. (Why? This is why.)

Limitations of MapKit Direction Requests

I’m trying to use MKDirection and MKDirectionsRequest to draw a bus route, but I am running into limitations with the API. I have an array of coordiantes of all 72 bus stops along the route, so my first task was to create an array of MKMapItems from those coordinates:

for item in coords {
    let mapItem = MKPlacemark(coordinate: item)
    mapItems.append(MKMapItem(placemark: mapItem))

So far, so good. The next step was to configure the the MKRoute and MKDirectionsRequest:

var busRoute = MKRoute()
let directionsRequest:MKDirectionsRequest = {
    let request = MKDirectionsRequest()
    request.transportType = .automobile
    request.requestsAlternateRoutes = false
    return request

Finally, iterate through the array of MKMapItems and calculate directions from the first stop to the last stop along the route:

for (count, item) in mapItems.enumerated() {
    if count < mapItems.count - 1 {
        directionsRequest.source = item
        directionsRequest.destination = mapItems[count+1]
        let directions = MKDirections(request:directionsRequest)
        directions.calculate(completionHandler: { (response, error) in 
            if error == nil {
                // Add the route to the map
                OperationQueue.main.addOperation {
                    busRoute = response!.routes[0]
                    self.busRouteMapView.add(busRoute.polyline, level: .aboveRoads)
                } else {

This worked as advertised, but only to a point: 50 direction calculations. When I hit 50 API calls, the error returned is Directions Not Available and it restricts any further API calls for about one minute, preventing any opportunity to chain requests together.1 Left as-is, MapKit would return directions for just under 70% of the route, which is obviously not acceptable.

As a test, I tried to use the first and last set of coordinates and then every second set of coordinates in between. Zoomed out, it looked promising. Zoomed in, not so much — it lead to cut corners.

I don’t want to use MKPolyline to draw a waypoint-to-waypoint look that would ignore the roads. For the moment, I am stuck.

  1. Unhelpfully, I’ve found no mention of this API limitation in the documentation. ↩︎

Vlogger Received Rocks and Bricks Instead of the Canon DSLR He Ordered  

Michael Zhang, for Petapixel:

A popular YouTube personality with over 780,000 subscribers has caused a stir by claiming that he ordered a $6,000 DSLR from Amazon but received a camera box filled with rocks instead. And when he was sent a replacement from Amazon, the second box was filled with bricks.

Chaseontwowheels, a motorcycle vlogger, documented his experience in the 12-minute video above. He says that he originally ordered a $6,000 Canon 1D X Mark II from Amazon — it’s unclear whether the order was sold directly by Amazon or was placed with a 3rd party — and received a legitimate camera box filled with heavy rocks instead (you can watch his original rant here).

I was recently very close to ordering a new Nikon DSLR from Amazon (US) but decided against it because I was concerned about Fulfilled by Amazon seller ratings and damage in transit. I can’t imagine how angry I would have been if I had ordered the camera and received rocks and bricks.

Trump Proposes Arming of Teachers  

David Smith, The Guardian:

Donald Trump has said he will consider a proposal to arm school teachers in an attempt to prevent mass shootings, a move certain to prove fiercely divisive.


Referring to Aaron Feis, a football coach who used his body as a shield to protect a student during the massacre at Marjory Stoneman Douglas high school in Parkland, the president continued: “If the coach had a firearm in his locker when he ran at this guy – that coach was very brave, saved a lot of lives, I suspect.

“But if he had a firearm, he wouldn’t have had to run, he would have shot him, and that would have been the end of it. This would only obviously be for people who are very adept at handling a gun. It’s called concealed carry, where a teacher would have a concealed gun on them. They’d go for special training and they would be there and you would no longer have a gun free zone.”

Guns in schools is not the solution to school shootings. As other countries have proven, the solution is fewer guns.

HomePod Leaves Prominent Marks on Certain Surfaces  

John Chase, Wirecutter:

We quickly discovered through testing that the HomePod leaves prominent white rings on unprotected wood, a potentially disastrous problem for owners of fine furniture. While Apple insists these marks are easily wiped away, it’s still something to consider.

Apple’s HomePod support document:

It is not unusual for any speaker with a vibration-dampening silicone base to leave mild marks when placed on some wooden surfaces. The marks can be caused by oils diffusing between the silicone base and the table surface, and will often go away after several days when the speaker is removed from the wooden surface. If not, wiping the surface gently with a soft damp or dry cloth may remove the marks. If marks persist, clean the surface with the furniture manufacturer’s recommended cleaning process. If you’re concerned about this, we recommend placing your HomePod on a different surface.

It’s not as disastorous as it’s being made out to be by Wirecutter. Just put a cloth under it.

Updated 2018-02-16: This also happens with the Sonos One.

Siri on HomePod Correctly Answered 52.3% of Queries in New AI Test  

Mitchel Broussard, Macrumors:

In a new test shared today by Loup Ventures, Apple’s HomePod was put through its paces in categories including Siri, sound quality, and ease of use. For Siri, Loup Ventures’ Gene Munster reported that while the AI assistant understood 99.4 percent of queries asked of it, it answered only 52.3 percent of them correctly. Loup Ventures tested three separate HomePods and asked 782 queries total.

It’s been almost eight years since Apple purchased Siri but it doesn’t feel like there has been eight years of progress. In the above test almost 1 in 2 questions couldn’t be answered correctly! While I’m not sure what questions were asked, below are some examples from my testing:

  • Birthdays: If you have a someone’s birthday recorded in the Contacts app, ask Siri how old that person will be on their next birthday. Siri will respond with said person’s current age. This is Siri working out the age based on data held locally within an Apple app — there is no way this should fail.
  • Localisation: Asking Siri what the next matches are in the Premier League gives two results for the same match. The text states Leicester City vs Stoke City, while the team crests are in the reverse order. This makes no sense as one is Home vs Away while the other is Away vs Home.
    • An additional minor gripe: why am I also told which U.S. TV channel is broadcasting the game? Siri could use my location (Singapore) and language preferences (English, U.K.) to determine this information to be completely unnecessary.
    Siri Localisation Fail

Siri needs some serious improvements.