Monday, April 12, 2021 [Tweets] [Favorites]

NHS COVID-19 App Rejected on Privacy Grounds

Leo Kelion (via MacRumors, Hacker News):

An update to England and Wales’s contact tracing app has been blocked for breaking the terms of an agreement made with Apple and Google.

The plan had been to ask users to upload logs of venue check-ins - carried out via poster barcode scans - if they tested positive for the virus. This could be used to warn others.


Under the terms that all health authorities signed up to in order to use Apple and Google’s privacy-centric contact-tracing tech, they had to agree not to collect any location data via the software.

Florian Mueller:

With UK shops, restaurants and pubs reopening today thanks to a relaxation of COVID prevention rules, it was actually a very smart idea for the NHS COVID-19 app to ask users to scan QR codes when entering such places, thereby enabling the system to inform people if they had been in a virus hotspot at a critical moment.

In the Western world, contact tracing has failed to make a noteworthy positive impact. In parts of Asia, however, those apps made a huge contribution because people were not even allowed to enter restaurants unless the contact-tracing apps on their smartphones greenlighted them (meaning they had not recently been near an infected person for a certain period). It made a whole lot of sense for the UK to adopt what worked in Asia.


About a year ago, Nature reported on contact tracing apps and mentioned that an earlier version of the NHS app was tested, “[b]ut because this app eschews Apple and Google’s protocol, it will not be able to run in the background on iPhones.” An expert called this “a nail in the coffin.” Obviously, contact tracing is of little use if you actually have to have the contact tracing app running in the foreground all the time.

How should Apple and Google weigh potential health benefits vs. privacy? And what about people who want to contribute their data but aren’t allowed to?


Logitech Harmony Remote Discontinued


While Harmony remotes are and continue to be available through various retailers, moving forward Logitech will no longer manufacture Harmony remotes.

We expect no impact to our customers by this announcement. We plan to support our Harmony community and new Harmony customers, which includes access to our software and apps to set up and manage your remotes. We also plan to continue to update the platform and add devices to our Harmony database. Customer and warranty support will continue to be offered.

Jason Snell:

This is real shame. I love my Logitech Harmony remote, and have bought them for my family in the past as well. This isn’t to say that the Harmony was awesome, just that it was better than any other option I’d tried.

But this demise has probably been a long time coming: a lot of people have fewer devices hooked up to their TVs now, many bundled remotes can control multiples devices, and technologies like HDMI-CEC have helped eliminate some needs for universal remotes.

Nick Heer:

For one, there are many other companies that maintain databases of IR remote control codes, not just Logitech, so those codes are not disappearing off the face of the planet just because Harmony is going away. Some of those databases are also open to the public, like this one on GitHub. There are also some other universal options that, like those from Logitech, have those codes in a database and do not require individual programming — Logitech’s Harmony line seems to be the default pick among buyers’ guides, but Joanna Stern’s choice was the Ray Super Remote and TechHive likes a Caavo model. Most importantly, the universal control problem is slowly fading as HDMI CEC becomes more widely used and different remotes can be used with different equipment.


Microsoft Acquires Nuance

Microsoft (via Hacker News):

Microsoft will acquire Nuance for $56.00 per share, implying a 23% premium to the closing price of Nuance on Friday, April 9, in an all-cash transaction valued at $19.7 billion, inclusive of Nuance’s net debt. Nuance is a trusted cloud and AI software leader representing decades of accumulated healthcare and enterprise AI experience. Mark Benjamin will remain CEO of Nuance, reporting to Scott Guthrie, executive vice president of Cloud & AI at Microsoft.

Microsoft has accelerated its efforts to provide industry-specific cloud offerings to support customers and partners as they respond to disruption and new opportunities. These efforts include the Microsoft Cloud for Healthcare, introduced in 2020, which aims to address the comprehensive needs of the rapidly transforming and growing healthcare industry.


Talon Beta


Talon aims to bring programming, realtime video gaming, command line, and full desktop computer proficiency to people who have limited or no use of their hands, and vastly improve productivity and wow-factor of anyone who can use a computer.

Voice Control: talk to your computer
Noise Control: click with a back-beat
Eye Tracking: mouse where you look
Python Scripts: customize everything

Via Nicholas Riley:

Talon now has great accuracy to go with its speed, robustness and cross-platform support (Mac/Win/Linux). It is also quietly a great Mac automation tool, including keyboard triggers, a version of appscript and accessibility hooks (example).

High Performance Numeric Programming With Swift

Jeremy Howard (via Frank Illenberger):

I’ve managed to create a couple of libraries that can achieve the same speed as carefully optimized vectorized C code, whilst being concise and easy to use. […] I will include examples mainly from my BaseMath library, which provides generic math functions for Float and Double, and optimized versions for various collections of them.


One of the really cool things about Swift is that wrappers like the above have no run-time overhead. As you see, I’ve marked them with the inlinable attribute, which tells LLVM that it’s OK to replace calls to this function with the actual function body. This kind of zero-overhead abstraction is one of the most important features of C++; it’s really amazing to see it in such a concise and expressive language as Swift.


Normally, because Swift has to handle the complexities of COW, it can’t fully optimize a loop like this. But by using a pointer instead, we skip those checks, and Swift can run the code at full speed. Note that due to copy-on-write it’s possible for the array to move if you assign to it, and it can also move if you do things such as resize it; therefore, you should only grab the pointer at the time you need it.


I think this is quite remarkable; we’ve been able to create a simple API which is just as fast as the pointer code, but to the class user that complexity is entirely hidden away.


I also find Swift’s performance is harder to reason about and optimize than C.


Friday, April 9, 2021 [Tweets] [Favorites]

Wix and Their Dirty Tricks

Matt Mullenweg:

Wix, the website builder company you may remember from stealing WordPress code and lying about it, has now decided the best way to gain relevance is attacking the open source WordPress community in a bizarre set of ads. They can’t even come up with original concepts for attack ads, and have tried to rip-off of Apple’s Mac vs PC ads, but tastelessly personify the WordPress community as an absent, drunken father in a therapy session. 🤔


They are so insecure that they are also the only website creator I’m aware of that doesn’t allow you to export your content, so they’re like a roach motel where you can check in but never check out.

Via Nick Heer:

Much like those recent Intel ads that also parody the Mac vs. PC campaign, Wix’s ads do not make much sense if you give them even a little extra thought. Take the one where a low-budget Bryan Cranston, playing the part of WordPress, collapses to the floor under the weight of forgotten maintenance and implores the site owner to switch to Wix. Sounds promising, except it is comparing a self-hosted software package to a managed platform, so it is not honest. Maintenance is not inherent to WordPress and, if you would prefer not to deal with it, there are managed options available through Automattic and many third-party providers.


I am not sure what these mean-spirited ads are supposed to achieve, but they do not make me want to recommend Wix to anyone. Quite the opposite. Other platforms are for nice people.

Roger Montti:

The campaign seemed to actually backfire by causing many to express negative reactions toward Wix.


Keyboard Shortcuts and non-US Layouts

Thomas Kainrad (via Hacker News):

During the past 15 months, I have been thinking a lot about keyboard shortcuts and about how different applications handle them. I shouldn’t complain; I knew what I was getting into when I started to build KeyCombiner, an app for learning and looking up shortcuts and text snippets. Still, I didn’t quite know how much of a mess keyboard shortcut handling on the web is.

Do you use an international keyboard layout? Then you already know what I am talking about. You probably have had some issues typing keyboard shortcuts such as alt+/, or cmd+[. This post will help you to understand why this annoyance exists. However, the people who should most urgently read this post are web developers. Are you a web developer? Great! I will explain how you are currently letting down non-US users and how you can get us out of this mess.

There are also issues for Mac apps. A shortcut that makes sense in one language or is ergnomic with one layout may not be with others.


But most importantly, I miss Android keyboard. Yes, I know, that I can install other keyboards, but on the one hand they not as good as on android, on the other hand, if anywhere, on iOS, I’d expect the system keyboard to work properly). I am a Hungarian student in France, I type on three languages on a daily basis. My main problems are[…]

Why There’s No iMessage for Android

Tim Hardwick:

It’s no secret that Apple sees iMessage as a big enough selling point to keep the service exclusive to Apple devices, however new court filings submitted by Epic Games in its ongoing lawsuit with the company reveal just how Apple executives have rationalized their decision not to develop a version of iMessage for Android.

Ben Lovejoy:

It seems Epic did manage to track down Scott Forstall’s phone number and depose him, as the former iOS senior vice president is cited as the source of one piece of evidence presented.

In an agenda for a 2010 executive team meeting, Apple founder and late CEO Steve Jobs wrote that he wanted to “tie all of our products together, so [Apple] further lock[s] customers into [its] ecosystem” [Forstall]

Eddy Cue also talked about what Apple does “to get people hooked to the ecosystem,” and Epic also presents evidence that this is why Apple never offered iMessage on Android.

Craig Federighi, Apple’s Senior Vice President of Software Engineering and the executive in charge of iOS, feared that “iMessage on Android would simply serve to remove [an] obstacle to iPhone families giving their kids Android phones” […]

Schiller commented that “moving iMessage to Android will hurt us more than help us.”

Nick Heer:

For some reason, this is being seen as a shocking admission.

John Gruber:

Apple first, users second, developers last — those are Apple’s priorities.

There are certainly reasons to believe that the exclusivity is good for Apple’s business, though it’s possible that if iMessage were cross-platform it would have become more dominant and that would have eventually accrued benefits to Apple.

But it’s a trade-off because this is definitely worse for Apple’s customers. The user experience and and photo/video quality are worse when exchanging text messages with Android-using friends and family. And they aren’t end-to-end encrypted. Selling more iPhones is more important than the privacy of those who already have iPhones.


Apple and Epic’s Proposed Findings of Fact

John Voorhees (also: Court Listener):

Just past midnight Pacific time today, Apple filed Proposed Findings of Fact and Conclusions of Law in its legal dispute with Epic Games. The document, a standard pre-trial filing, is designed to serve as a road map for the trial judge, explaining the facts Apple expects will be admitted into evidence at trial, how the law applies to those facts, and the decision Apple believes the court should reach. In other words, it’s a one-sided account of the disputes meant to persuade the judge that Apple’s legal positions are correct. Epic has filed a similar pleading in the case arguing its side of the story.

Juli Clover:

Tim Sweeney, the CEO of Epic Games, has confirmed Project Liberty in prior interviews and has said that Epic spent months preparing the lawsuit against Apple, though Apple’s court filings provide new insight into the lengths that Epic went to in order to rope Apple and Google into an antitrust lawsuit.

Apple argues that an expansion of antitrust law is unwarranted and that Epic’s product market descriptions are inaccurate because of the other platforms the App Store is competing with. Apple claims that Epic overstates the App Store’s profitability, and that arguments that the review process is ineffective are inaccurate.

Samuel Axon:

The major distinction at play in Epic’s own argument is that iOS is an entire market unto itself and not just one of many competing products in a larger marketplace of video game transactions. If the judge agrees with this classification, Apple may be more likely to be seen as monopolistic.

Another key part of Epic’s argument involves comparing and contrasting iOS with macOS. Apple claims that its strict rules about what apps can and can’t do on the iOS App Store are driven at least in part by concerns about security and privacy for users. Epic points out, however, that Apple claims macOS is secure and private without placing all the same restrictions on the Mac operating system.


Epic asserts that Apple’s controversial App Review process “does little to keep iOS devices secure,” and it alleges that Apple has on multiple occasions screened apps “primarily for non-security issues—including specifically for anti competitive purposes.”

Apple (PDF):

Apple has never increased its baseline 30% commission. Schiller TT. To the contrary, it has lowered the commission in multiple instances, including subscription services and as part of its small business program.

As I’ve noted, the effective commission has actually increased. The recently announced small business program of course has nothing to do with this case.

When those free downloads are considered—as they should be—the effective commission rate for initial game app downloads in 2008 was about 3%


Both categories of evidence—market structure and market outcomes—are inconsistent with Apple possessing monopoly power or charging supracompetitive prices.


Developers need not even leave the App Store to constrain Apple’s ability to raise prices. Hitt TT. If Apple sought to raise its commission, for example, developers could monetize through content or digital currencies sold to consumers through another transaction platform or directly through a web browser (including a web browser on an iOS device).


IAP obviates the need for (and expense of) tracking, audit, and collection of Apple’s commissions on any in-app purchases of digital content. Schmalensee TT. Indeed, without such automatic processes, a developer using an external payment mechanism could seek to evade a commission owed to Apple, and Apple would have no technological ability to collect any commissions on the sale. Schmalensee TT. This would lead to laborious reconciliation efforts and dispute resolution—turning an automated, near-instantaneous process accomplished through IAP into a fraught and drawn-out one.

It’s weird how Apple is simultaneously arguing that developers have other options for payments and that no other options can be allowed because that would make it harder to count up the 30% that’s owed to Apple.

Florian Mueller:

By mislabeling distributor and retailer margins as “commissions,” Apple seeks to distract from structural differences between shrinkwrapped software distribution and today’s app stores.

Epic (PDF):

In the months that followed, Apple executives and software engineers debated the proper distribution method for third-party applications and specifically whether “Apple signed applications” would be posted exclusively to an “online store”, or whether third parties would be permitted to “distribute on their own”. […] Apple’s security experts remained out of this debate, noting that the question of exclusive distribution is one of “policy”, as opposed to security.


During the time between the launch of the App Store in 2008 and the introduction of IAP in 2009, in-app payment processing and app distribution were entirely separate and iOS developers were monetizing their apps with in-app payment solutions that were self-provided.


Web apps have limited functionality compared to native apps. Native apps are “faster”, “use less memory” and “can take advantage of native graphics libraries in a way that is either not available or would have to be shoehorned in a web app or a different kind of application”. (Forstall Dep. […])


Apple publicly touts the security of macOS, promising Mac users that they can enjoy “Security. Built right in.” and can “[d]ownload apps safelty from the Mac App Store. And the internet.”


Apple prepared a number of internal white papers [that] explicitly contemplate the possibility of distribution outside the App Store, and assume that “the technical infrastructure [they were] building w[ould] allow for other distribution mechanisms” beyond the App Store. […] This security layer is independent of the app distribution channel.


In 2013, another app from the same developer was “remov[ed]” “immediately” because Mr. Schiller and Mr. Cue were “adamant” about its removal, despite Mr. Shoemaker’s “protest[s]” that there was no clear justification for doing so under the app review guidelines.


The FEAR team further believed that […] the process amounts to “a wetware [i.e., a human-led] rate limiting service and nothing more”, and that Apple had not invested sufficient resources to detect and prevent abuse.

Florian Mueller:

Epic: “In June 2018, Apple sought to force Uber and Lyft to adopt IAP for their newly-introduced subscription services.” The remainder of that paragraph is redacted. Was it previously known that Apple tried to require Uber and Lyft to use Apple’s payment system for subscriptions?

Patrick McGee:

Eric Friedman, head of Apple’s FEAR unit — Fraud Engineering Algorithms and Risk — said in a recent deposition that his team believed the App Review team was inadequate to the risks posed by malicious actors, saying they were “bringing a plastic butter knife to a gun fight.”


However in late 2017 Apple’s FEAR team still called the App Review process inadequate. Friedman said it “was more like the pretty lady who greets you with a lei at the Hawaiian airport than the drug sniffing dog.”

FEAR likened App Review to TSA employees, “under pressure to move people through” and “not able to deflect sophisticated attackers”.

Jeff Johnson:

There shouldn’t be anything particularly surprising to knowledgeable App Store developers. But this is public confirmation that the worst case scenarios, our most “cynical” speculations, are actually true.

Nick Lockwood:

I can’t believe how long Apple has had to address these problems and how little they’ve done.

David Heinemeier Hansson (tweet):

Apple’s App Store was never designed to work. At least not in the way the company purports that it does. Apple presents the App Store as a highly curated, secure mall of apps which have been thoroughly vetted, and that you can safely install without any due diligence. But it’s not and you shouldn’t.

As part of Epic’s lawsuit against Apple, we’ve come to learn that app reviewers typically review 50-100 apps per day. Some times spending less than a minute reviewing an individual app. We’ve also learned that these reviewers are hired without any technical background, let alone any particular expertise with the iOS or macOS platforms.

There’s a term for a practice like this: security theater.

Tony Fadell:

Customers convinced us but so did the fact that Google LOVED that we started with a web apps strategy. Eric Schmidt was a huge supporter & it’s easy to understand why. When SJ saw he could lose control of the iPhone platform, there was a whole hearted shift away from web apps!


Wednesday, April 7, 2021 [Tweets] [Favorites]

New Outlook’s Dangerous “Discard” Shortcut

Nick Heer:

Microsoft has two different versions of Outlook in the Outlook for Mac app. One of the keyboard shortcuts changed in New Outlook compared to the “classic” Outlook app is Command–Shift–D. In Apple’s Mail app, this is the shortcut for sending a message. In New Outlook, it discards the message you have just finished writing — without warning or confirmation — where it disappears into the aether.


Resources for Learning SwiftUI

Jesse Squires:

A few months ago, I shared my notes and resources for learning about compilers and LLVM. It turned out to be pretty popular and folks seemed to find it useful. So I decided to do it again, but this time for SwiftUI.


Despite not yet using SwiftUI, I do want to. And I know that eventually, I will need to. That is why I have been reading blog posts and keeping notes. All of these notes live in my public TIL repo.


The Former Netflix DVD Library Is a Lost Treasure

Jim Vorel:

It’s a strange feeling, to look back to a time merely 10 years ago and think “that was a golden era, wasn’t it?” It feels like it should take longer than a decade for that kind of clarity to develop, but the more time I spend looking at the streaming service landscape as a Paste staff writer, the more I find myself returning to the same conclusion: Netflix, as a service, could once say it offered a film library that was unmatched by any other archive of films in the world. Just a decade ago, the physical media library possessed by Netflix was well beyond 100,000 titles strong, offering a staggering degree of diversity that essentially made it the equivalent of the best-stocked video store in the world. At its peak, in fact, the number of DVD titles possessed by Netflix would have dwarfed the entire streaming libraries of all the major streamers today … combined.


The shrinking of the physical Netflix DVD library has been a simple enough process to observe for customers who are paying attention to their queue of upcoming deliveries. As the years have gone by, I’ve watched my own queue be decimated by this process, with titles first moving from “queue” to “saved” (essentially a request that Netflix obtain a DVD they no longer have), to then disappearing from the service entirely. Many films I borrowed from Netflix in the last decade no longer show up at all when searched at, and they’re exactly the sort of movies you would expect to see disappearing—cult films, foreign films, obscure titles, B-movies, etc.

Via Nick Heer:

The curious thing is that these services are both balkanized — in that they have vast amounts of stuff licensed exclusively to one service — and conglomerated — there are only a handful of parent companies that own all of Hollywood’s major studios. So instead of the music streaming model, where most people just pay for one service and then listen to a massive catalogue of music ranging from mainstream hits to independent artists, the movie industry thinks we’re all going to pay for each of their siloed services[…]


History of Flow vs. Asana

Andrew Wilkinson:

This is a story about how I lost $10,000,000 by doing something stupid.


It turned out that Dustin Moskovitz (@moskov), the billionaire co-founder of Facebook, was a fellow to-do list junkie, and he was quietly working on his own product.


It was ugly! It was designed by engineers. Complicated and hard to use.

Not a threat in the slightest.


Suddenly, Asana ads were everywhere.


In order to stay competitive, we had underinvested in our engineering team due to cash constraints and stretched them across mobile, desktop, and web.


We lost the war, due to inexperience, product myopia, and a lack of capital in a highly capital intensive and competitive space.

David Heinemeier Hansson:

Flow spread itself thin thinking “the market” had set certain non-negotiable bars, so unless they had, say, an Android app RIGHT NOW, they’d be toast. This led to a me-too, low-quality product full of bugs. Instead of focusing on a smaller, more opinionated, more differentiated product.


Wilkinson’s tale of regret is steeped in war metaphors. Bringing bigger, badder weapons to this imaginary war with Asana. Locked into a Cold War one-upping game. Of course you’re going to lose if you define your company and your product on the competition’s terms, try to copy whatever they’re doing, but don’t have half the money to do so.


If you run your company like it was VC funded without the venture capital, yeah, you’re going to wish you had just taken other people’s money.

Tuesday, April 6, 2021 [Tweets] [Favorites]

Swift “Collections” Package

Karoy Lorentey (tweet):

I’m thrilled to announce Swift Collections, a new open-source package focused on extending the set of available Swift data structures. Like the Swift Algorithms and Swift Numerics packages before it, we’re releasing Swift Collections to help incubate new functionality for the Swift Standard Library.


The main benefit of Deque over Array is that it supports efficient insertions and removals at both ends.


OrderedSet is a powerful hybrid of an Array and a Set.


OrderedDictionary is a useful alternative to Dictionary when the order of elements is important or we need to be able to efficiently access elements at various positions within the collection.


Use Emergency Bypass to Circumvent Do Not Disturb

Josh Centers and Adam Engst:

What’s the difference between Allow Calls From and Emergency Bypass? In essence, you can use Emergency Bypass to allow both calls and text messages. However, it’s not as straightforward as Allow Calls From. There’s no mention of Emergency Bypass in the Do Not Disturb settings, you have to find and enable it for individual contacts, and you shouldn’t confuse it with the unrelated Emergency Contacts used for Medical ID notifications.


There is one potentially unexpected caveat. If your Mac is awake and running Messages, it will likely capture text messages before they’re sent to your iPhone. In most situations, that’s sensible—you don’t want text message notifications to make sounds on every Apple device you own if you’re actively using your Mac. Obviously, if you’re away from your Mac, it should be sleeping, but if that’s not true for some reason, it could prevent messages from arriving on your iPhone regardless of Emergency Bypass.


The only thing to keep in mind is that Emergency Bypass will cause your iPhone to make sounds even if Do Not Disturb is on and the ring/silent switch is enabled. That’s the point, of course, but there are situations where silence is essential—a recital, a play, a meditation class. In other words, if Emergency Bypass overrides Do Not Disturb, how can you override Emergency Bypass every so often? Editing individual contact cards is clearly too much work. We found two levels of workaround[…]

This seems so complicated. But, then, it’s also not so simple to describe how you want it to behave.

Switching Back to Mac

Carlos Fenollosa (via Hacker News):

Due to very bad decisions by Apple’s product marketing teams, Mac hardware and software had been in steady decline since 2016.

Therefore, there has been a trickle of articles on the Geekosphere about people switching from Macs to Linux or Windows.

This is the contrarian view. Don’t do it.

The TL;DR is right there in the title: migrating to Linux is fine, but don’t expect a better experience than the Mac.

He really liked the Nautilus file manager, though.


Monday, April 5, 2021 [Tweets] [Favorites]

Copying the Java API Was Fair Use

James Romoser (tweet, Hacker News):

The Supreme Court on Monday sided with Google over Oracle in a major copyright battle, ruling that Google’s copying of a portion of the Java SE computer program is protected as “fair use.”

The ruling in Google v. Oracle was 6-2, with Justice Stephen Breyer delivering the opinion of the court.


In siding with Google, Breyer wrote that, assuming for the sake of argument that the lines of code can be copyrighted, Google’s copying is nonetheless fair use.

Mike Masnick:

The background of this case is actually kind of important to understanding what just happened, so here’s a quick(ish) recap.


One of the big debates in the lead up to the case, and at oral arguments, was what “analogy” best represented what an API was. You can see above Breyer mention the Dewey Decimal System, which is a pretty good analogy.


Breyer then notes that even though Google asked the Court to say APIs are not covered by copyright, since they can answer the fair use question and dispose of the issue, the court will just assume that APIs are subject to copyright for the sake of exploring fair use, and leave the actual question of copyright and APIs to another day (groan).

Charles Duan:

SCOTUS doesn’t just rule in favor of Google in @googlevoracle, but says that API reimplementation is fair use as a matter of law, meaning that the decision applies to all APIs


Anyway, this is great news for software folks. The concern was that SCOTUS could just let the jury decision stand, solving Google’s case but leaving an open question for all future software developers.

Florian Mueller:

Given that the justices were pretty much unanimously leaning toward copyrightability in October, it would be quite risky for anyone to consider API declaring code uncopyrightable. However, technically the Federal Circuit’s copyrightability decision hasn’t been affirmed either.


There’s plenty of people out there now who are celebrating today’s Supreme Court decision as promoting innovation, competition, and openness. In reality, the net effect will be the opposite. When Sun created Java, they allowed everyone to make and publish apps for it. Sun adopted a dual-licensing model under which you could either get Java under the GPL free software license or take a commercial license. Sun is history--it was acquired by Oracle. The next company contemplating the development of a comparable platform will look at what happened in Oracle v. Google. Against that background, it may either be discouraged from making the investment in the first place--or it may be encouraged to pursue an Apple-like platform business model (“walled garden”) and create network effects through a non-open system with cloud components, an exclusive app store, and so forth. In other words, if you can’t own software, you’ll try to own (access to) users.


The ruling managed to find its way to a reasonable outcome, but if these are the tools used to chisel fundamental conditions for developers, companies and people the world over, we are all in bad shape for the future.

John McCall:

Yes, I think this decision does strongly imply that the GNU position that linking a library can be controlled by copyright is incorrect


Facebook Breach

Tim Hardwick (Hacker News):

The personal details of more than 553 million Facebook users have been published on a website for hackers, according to multiple reports over the weekend.


In a statement, Facebook said the data was from a breach of its servers that had occurred in 2019 and it had since plugged the security hole that allowed it to take place.

While the information appears to be old, the details in the shared database include phone numbers, Facebook IDs, names, locations, birthdates and email addresses, all of which could be used in social engineering attacks or hacking attempts.

None of those is easy for users to change.

David Sparks:

If you have a Facebook account, now is the time to be on alert for scammy phone calls from people who will try and social engineer their way into your credit card numbers and bank accounts. There is already a scam where they call and claim to be the IRS and need “immediate payment to avoid criminal prosecution”. I’m sure they’ll come up with even more dreadful ways to abuse this treasure trove of data.


Yahoo Answers Shutting Down

Nick Statt:

Yahoo Answers, one of the longest-running and most storied web Q&A platforms in the history of the internet, is shutting down on May 4th. That’s the day the Yahoo Answers website will start redirecting to the Yahoo homepage, and all of the platform’s archives will apparently cease to exist. The platform has been operating since 2005.

Yahoo, which is now part of Verizon Media Group following the company’s sale to the telecom for nearly $5 billion in 2017, announced the change at the top of the Yahoo Answers homepage. The message links to an FAQ, which details the timeline of the shutdown.


Tim Cook on Sideloading

Sami Fathi (tweet):

In a wide-ranging interview with The New York Times’ Kara Swisher, on her podcast “Sway,” Apple CEO Tim Cook talks about Apple’s feud with Facebook, its stance on privacy, Apple’s legal battle with Epic Games, and possible future Apple innovations such as Apple Glasses.


One of Epic Games’ biggest arguments about the Apple ecosystem is the lack of so-called “freedom” for users to download apps from places other than the App Store. Many have long voiced their hope that Apple would allow users to sideload apps onto their device, such as the iPhone. Cook says that sideloading apps, however, would “break the privacy and security” model of the iPhone.


Apple Music macOS Review

Your Product Sucks:

Apple Music app on macOS Catalina is “not so great”

This one can’t be blamed on Catalyst.

Via John Gruber:

Music on Mac is just an utter embarrassment for Apple. Truly an ignominious fate for iTunes, which started 20 years ago as an exemplar of a great Mac app.


Friday, April 2, 2021 [Tweets] [Favorites]

Snapchat’s App Tracking Transparency Workaround

Juli Clover:

Apple has begun rejecting app updates that do not comply with the App Tracking Transparency rules that the company is enforcing starting with iOS 14.5, according to a new report from Forbes.

Apps must ask for permission to access the advertising identifier or IDFA of a user’s iPhone in order to track them across apps for ad targeting purposes, a rule that apps will need to comply with when iOS 14.5 launches. The rule also prevents apps from using other workaround methods for tracking users, which is getting some developers into trouble already.

Ben Lovejoy:

Snapchat owner Snap has tested a workaround to App Tracking Transparency using a technique that has a success rate of around 95% in identifying individual users.

Snap says that it will discontinue the tests once the new privacy rule comes into effect, but that it believes there are other steps it can take without breaking Apple’s rules…


Snap admitted to the FT that it has been running the tests, but said it would cease doing so when the App Tracking Transparency rules take effect in the next few weeks.


Apple Arcade Adds Classic Games

Sami Fathi:

Apple today announced that its mobile gaming subscription service, Apple Arcade, is gaining 30 classic games including “Fruit Ninja,” “Monument Valley,” “Solitaire,” and “Cut the Rope” as the service passes a total of 180 titles.


The Mac Needs Shortcuts

Jason Snell:

The problem is that today, everything about user automation on Apple’s platforms is fractured. On the Mac, the technologies feel old-fashioned, adrift, and increasingly unsupported. On iOS, Shortcuts has some weaknesses and an every-app-for-itself mindset prevails. And between the two platforms there’s no connectivity at all.


As much as I like the impetus behind Automator—automation for the masses!—it died on the vine. Apps didn’t support it well, and Apple failed to provide a robust enough library of actions to make it work well on its own. If I ever thought Automator was okay, one glance at Shortcuts (or its predecessor, Workflow) would disabuse me of the notion. Still, I end up using Automator regularly because it allows me to integrate AppleScript and unix/shell scripting directly into the Finder.


It’s clear to me now: Apple needs to make Shortcuts available everywhere.


That’s a lot to ask, but since I’m on a roll, I’ll once again suggest that Apple needs to more explicitly support scripting languages on both platforms.


“Foil” UserDefaults Property Wrapper

Jesse Squires (tweet):

UserDefaults is one of the most misused APIs on Apple platforms. Specifically, most developers do not handle default values correctly. In fact, I have never worked on a single production codebase at a company where this was done accurately. Most libraries get it wrong, too.


There are a few libraries that currently provide a property wrapper for UserDefaults. However, the ones that I know about each have a combination of the following issues: (1) default values are not registered, (2) optionals are not handled nicely, (3) the library is extremely complicated for such a simple task.

I like his approach. Mine differs in that:


YouTube Testing Removal of Dislike Count

YouTube (via Hacker News):

In response to creator feedback around well-being and targeted dislike campaigns, we’re testing a few new designs that don’t show the public dislike count.

This seems like a bad idea, as dislikes were a good, quick indicator that a video might be misleading or at least controversial.


Aho and Ullman Win Turing Award

ACM (via Hacker News, Cade Metz):

ACM named Alfred Vaino Aho and Jeffrey David Ullman recipients of the 2020 ACM A.M. Turing Award for fundamental algorithms and theory underlying programming language implementation and for synthesizing these results and those of others in their highly influential books, which educated generations of computer scientists.


“Aho and Ullman established bedrock ideas about algorithms, formal languages, compilers and databases, which were instrumental in the development of today’s programming and software landscape,” added Jeff Dean, Google Senior Fellow and SVP, Google AI. “They have also illustrated how these various disciplines are closely interconnected. Aho and Ullman introduced key technical concepts, including specific algorithms, that have been essential. In terms of computer science education, their textbooks have been the gold standard for training students, researchers, and practitioners.”

I have fond memories of Compilers: Principles, Techniques, and Tools, which everyone called the Dragon Book.


Long Term iPhone 12 Camera Review

Sebastiaan de With:

The only time that I found the smart image processing on the iPhone noticeably bothersome is when skies get overly tinted blue. It’s clear that the iPhone can now easily detect and segment the sky in a shot, and it applies nice smooth noise reduction to it to get wonderful gradients. But even cloudy skies tend to get a blue cast that isn’t as neutral as you’d like.


Initially, I hadn’t tested Portrait + Night mode very much. In the few tests I did, though — comparing it to a regular camera and the iPhone 12 mini, which is unequipped with a LIDAR sensor, it works outrageously well[…]


Flaring on the ultra wide and wide cameras is not just noticeable, but outright bothersome when shooting into light. In the above image, you can see the telltale iPhone ‘green orb’ flare that is a result from internal reflections in the lens. This can be fairly unobstrusive as in that shot, but when shooting many bright point sources of light head-on, can outright ruin a shot.


Noise reduction is something I never really enjoyed on iPhones, and I find it really bothersome that ProRAW does not give granular control over how much is applied to a final image. When shooting in dark conditions with the iPhone’s less light-sensitive cameras, you can get muddled images that would’ve looked nicer with some grain. It’s almost like a watercolor painting[…]


Wednesday, March 31, 2021 [Tweets] [Favorites]

Goodbye, Cortana

Tim Hardwick:

Microsoft today discontinued its Cortana mobile app. As a result, the company has ended all support for third-party Cortana skills and eliminated the Cortana app for iOS and Android devices.


The eponymous mobile app was originally launched in November 2018, but apparently never gained a user base big enough in its short lifetime for Microsoft to consider it worth maintaining.


Update (2021-03-31): Tanner Bennett:

Not that I would have even used it, but Cortana as an app could never compete with the built in virtual assistant. It’s a shame regulatory action hasn’t ever been taken to force Apple to allow us to set a default assistant.

Subscribing to Updated Blog Posts

Readers of this blog have been asking for an RSS feed for the recently Recently Updated page. I have not figured out how to do this with WordPress yet. However, with NetNewsWire 6 it is now possible to subscribe to a Twitter search of the #mjtsaiupdate tweets that I post.


How to Set Up Core Data and CloudKit

Becky Hansmeyer (tweet):

Turns out, if you want to sync Core Data-backed data between devices and have those changes reflected in your UI in a timely manner, you have some more work to do. To figure out what that work is, you can’t look at Apple’s Core Data templates. You have to look at their sample code.


Don’t be like me: make sure your schema is deployed.

After launch, remember that you still have to do this every time you change your Core Data model, before you release your update to testers or the App Store. If your production CloudKit schema doesn’t properly correspond to your production Core Data model, syncing is going to break in all kinds of terrifying ways.


Making NSFetchRequest.fetchBatchSize Work With Swift

Apple Frameworks Engineer:

Set in Swift is an immutable value type. We do not recommend making Core Data relationships typed this way despite the obvious convenience. Core Data makes heavy use of Futures, especially for relationship values. These are reference types expressed as NSSet. The concrete instance is a future subclass however. This lets us optimize memory and performance across your object graph. Declaring an accessor as Set forces an immediate copy of the entire relationship so it can be an immutable Swift Set. This loads the entire relationship up front and fulfills the Future all the time, immediately. You probably do not want that.

It’s so convenient, though, and often it doesn’t matter because it’s a small relationship or one that you will be fully accessing anyway. Perhaps the answer is to provide a duplicate set of NSSet accessors for use when you want the lazy behavior enabled by the class cluster.

Similarly for fetch requests with batching enabled, you do not want a Swift Array but instead an NSArray to avoid making an immediate copy of the future.

Needless to say, the documentation doesn’t mention this, but it does do a good job of explaining what fetchBatchSize does:

If you set a nonzero batch size, the collection of objects returned when an instance of NSFetchRequest is executed is broken into batches. When the fetch is executed, the entire request is evaluated and the identities of all matching objects recorded, but only data for objects up to the batchSize will be fetched from the persistent store at a time. The array returned from executing the request is a proxy object that transparently faults batches on demand. (In database terms, this is an in-memory cursor.)

You can use this feature to restrict the working set of data in your application. In combination with fetchLimit, you can create a subrange of an arbitrary result set.

Under the hood, this works by eagerly fetching the object IDs and lazily fetching and caching the objects, in batches, as they are accessed. The implementation is more optimized than what you could implement yourself, passing the object IDs to SQLite via temporary tables rather than as parameters to the SQL statement. There are some caveats to be aware of:

So, how do you get the optimized fetchBatchSize behavior when using Swift? The Apple engineer suggests using an NSArray, which I take to mean casting the result of the fetch via as NSArray to disabling automatic bridging and give your Swift code the original NSArray. However, my experience is that this doesn’t work. All the objects get fetched before your code even accesses the array. I think it’s because the special as behavior is for disabling bridging when calling Objective-C APIs from Swift, but NSManagedObjectContext.fetch(_:) is an overlay method implemented in Swift, not just a renaming of -[NSManagedObjectContext executeFetchRequest:error:].

This can be worked around by using an Objective-C category to expose the original method:

@interface NSManagedObjectContext (MJT)
- (nullable NSArray *)mjtExecuteFetchRequest:(NSFetchRequest *)request error:(NSError **)error;

@implementation NSManagedObjectContext (MJT)
- (nullable NSArray *)mjtExecuteFetchRequest:(NSFetchRequest *)request error:(NSError **)error {
    return [self executeFetchRequest:request error:error];

Then you can implement a fetching method that preserves the batching behavior:

public extension NSManagedObjectContext {
    func fetchNSArray<T: NSManagedObject>(_ request: NSFetchRequest<T>) throws -> NSArray {
        // @SwiftIssue: Doesn't seem like this cast should be necessary.
        let protocolRequest = request as! NSFetchRequest<NSFetchRequestResult>        
        return try mjtExecute(protocolRequest) as NSArray

    func fetch<T: NSManagedObject>(_ request: NSFetchRequest<T>,
                                   batchSize: Int) throws -> MJTBatchFaultingCollection<T> {
        request.fetchBatchSize = batchSize
        return MJTBatchFaultingCollection(array: try fetchNSArray(request))

The first method gives you the NSArray, but that is not very ergonomic to use from Swift. First, you have to cast the objects back to your NSManagedObject subclass. Second, it doesn’t behave well when an object is deleted (or some other SQLite error occurs) between your fetch and when Core Data tries to fulfill the fault.

If you’re using Swift, you can’t catch the NSObjectInaccessibleException, so you should be using context.shouldDeleteInaccessibleFaults = true. This means that instead of an exception you get a sort of tombstone object that’s of the right class, but with all its properties erased.

But it’s hard to remember to check for that each time you use one of the objects in the NSArray, and you probably don’t want to accidentally operate on the empty properties. So the second method uses a helper type to try to make the abstraction less leaky, always giving you either a valid, non-fault object or nil:

public struct MJTBatchFaultingCollection<T: NSManagedObject> {
    let array: NSArray
    let bounds: Range<Int>

    // array is presumed to be a _PFBatchFaultingArray from a fetch request
    // using fetchBatchSize.
    public init(array: NSArray, bounds: Range<Int>? = nil) {
        self.array = array
        self.bounds = bounds ?? 0..<array.count

extension MJTBatchFaultingCollection: RandomAccessCollection {
    public typealias Element = T?
    public typealias Index = Int
    public typealias SubSequence = MJTBatchFaultingCollection<T>
    public typealias Indices = Range<Int>
    public var startIndex: Int { bounds.lowerBound }
    public var endIndex: Int { bounds.upperBound }
    public subscript(position: Index) -> T? {
            let possibleFault = array[position] as? T,
            let context = possibleFault.managedObjectContext,
            // Unfault so that isDeleted will detect an inaccessible object.
            let object = try? context.existingObject(with: possibleFault.objectID),
            let t = object as? T else { return nil }
        return t.isDeleted ? nil : t

    public subscript(bounds: Range<Index>) -> SubSequence {
        MJTBatchFaultingCollection<T>(array: array, bounds: bounds)

extension MJTBatchFaultingCollection: CustomStringConvertible {
    public var description: String {
        // The default implementation would realize all the objects by printing
        // the underlying NSArray.
        return "<MJTBatchFaultingCollection<\(T.self)> bounds: \(bounds)>"

It’s still a bit leaky, because you have to be careful to only access the collection from the context’s queue. But this is somewhat obvious because it has a separate type, so you’ll get an error if you try to pass it to a method that takes an Array.

The batch faulting behavior and batch size are preserved if you iterate over the collection or slice it. (When iterating the NSArray directly, small batch sizes don’t work as expected because NSFastEnumerationIterator will always load at least 16 objects at a time.)


Replacing vs. Migrating Core Data Stores

Apple Frameworks Engineer:

Additionally you should almost never use NSPersistentStoreCoordinator’s migratePersistentStore method but instead use the newer replacePersistentStoreAtURL. (you can replace emptiness to make a copy). The former loads the store into memory so you can do fairly radical things like write it out as a different store type. It pre-dates iOS. The latter will perform an APFS clone where possible.

Tom Harrington:

[This] method is almost totally undocumented, so you’re on your own working out how to use it. The dev forums post mentioned above is from summer 2020. The replacePersistentStore(...) method was introduced five years earlier in iOS 9, but the forum post was the first time most of the information appeared.

[This] is the first suggestion I’ve seen that migratePersistentStore(...) might not be a good idea anymore. It’s not deprecated and I haven’t seen any previous source recommending against its use.

There are some comments in the header.

Incidentally you won’t find this if you’re using Swift and ⌘-click on the function name. You need to find the Objective-C header. One way to do this in Xcode is to press ⌘-shift-O and start typing the class name.


Its declaration says it can throw. I tried intentionally causing some errors but it never threw. For example, what if sourceURL points to a nonexistent file? That seems like it would throw, especially since the function doesn’t return anything to indicate success or failure. It doesn’t throw, although there’s a console message reading Restore error: invalidSource("Source URL must exist").

He’s figured out a lot, though other important details like the APFS support remain a mystery.

Tom Harrington:

The demo app I’ve been using is now on GitHub. You can take a look here. Or go directly to the diff of replacing migrate with replace here.


The backup process is simpler than it used to be, because replace doesn’t have the same side-effect that migrate did of unloading the persistent store.


Even though the migrate and replace methods seem pretty similar, the semantics are slightly different when the destination is a currently-loaded store. My new restore code reflects that.


Tuesday, March 30, 2021 [Tweets] [Favorites]

More Apple Repair Providers and Lobbying

Apple (MacRumors, Hacker News):

Apple’s Independent Repair Provider program will soon be available in more than 200 countries, nearly every country where Apple products are sold. Launched originally in 2019 and expanded to Europe and Canada last year, the program enables repair providers of all sizes access to genuine Apple parts, tools, repair manuals, and diagnostics to offer safe and reliable repairs for Apple products. There are now more than 1,500 Independent Repair Provider locations serving customers across the US, Canada, and Europe.

Sami Fathi (tweet):

Apple, HP, and Honeywell are lobbying against a bill in the Nevada statehouse that would require electronic hardware manufacturers to provide device schematics, device parts, and instructions to third-party repair shops for device repairs, according to the Associated Press.


The bill aims to remove the requirement for customers to go to authorized dealers for repairs by allowing them to use smaller independent repair shops as well. Apple has long faced pressure to expand accessibility to device parts and schematics, and it’s previously put up battles to maintain its tight control over device repairs.

Cameron Demetre, the regional executive director of TechNet, a trading group representing Apple, HP, and Honeywell in committee hearings on the bill, says that his clients are concerned about the potential exposure that third-party repair shops will have to personal users’ data when repairing devices.

I get that Apple repeats the word “privacy” a lot, but is there actually any reason to believe that its repair subcontrators are more likely to treat users’ data well? And we already know that it requires its IRPs to report customers’ personal data back to the mothership.


WWDC 2021 Announced and New Developer App


Apple today announced it will host its annual Worldwide Developers Conference (WWDC) June 7 through 11, in an all-online format. Free for all developers, WWDC21 will offer unique insight into the future of iOS, iPadOS, macOS, watchOS, and tvOS.


We’ve made improvements to the look and feel of the Developer app across iPhone, iPad, and Mac to help you enjoy articles, videos, news and announcements, and past WWDC content. You can browse content more easily on iPad with a new sidebar (iPadOS 14 or later), enjoy fullscreen video content on larger Mac displays, and discover content to watch and read using the new Search area.

John Voorhees (also: MacRumors):

The sidebar of Developer is now easier to navigate. On the iPhone and iPad, content categories, such as Design, Frameworks, and Graphics and Games, can now be collapsed, greatly reducing the amount of vertical scrolling when browsing news and sessions. The iPhone and iPad versions of the app use a more compact, tile-based layout for the Discover tab, which allows for more items to be featured too. The design works well on the smaller screen of the iPhone, but where it really shines is on the iPad and Mac’s larger screens.

The Mac version crashes at launch on Catalina. I also tried it on Big Sur, where it’s better than before but still just a bad app. This is Apple’s example to developers of how to make a universal app using Catalyst. It’s been almost two years now since Craig Federighi said the Catalyst apps were going to get “really good.” Are any of them good now? I see Maps praised a lot, but the arrow keys don’t work properly in its sidebar, and its preferences look funny.


Sparse Files Are Common in APFS

Howard Oakley:

Increasing numbers of files written by all sorts of different apps and services consist of large voids, between islands of meaningful data. Storing lots of void data is wasteful, so what APFS tries to do is store only the real data.


Sparse files are kept in sparse format as much as possible, and when copied or duplicated within the same volume should be kept in sparse format. Copying them between different volumes and disks isn’t so predictable, and sometimes leads to them ‘exploding’ to full size. That is normal when they’re copied to file systems like HFS+ which don’t support sparse files, and to iCloud.

You should expect all sparse files to be expanded fully when they’re backed up to HFS+ disks, as with Time Machine prior to Big Sur, which may not estimate their expanded size correctly either, as I have described. Expansion takes place at the source of a copy: for example, if you copy a sparse file from your internal APFS disk to an external disk in HFS+ format, the full expanded size of data will have to be copied across to the external disk.


Throughout my quest for these elusive sparse files, I had assumed that only certain apps could create them. That isn’t true: macOS now defaults to creating all files in sparse format when certain conditions are met.


When you use the FileHandle class to create a new write handle, a sparse file is created automatically. For example, if you write a block of data, then seek one block by calling seek(toFileOffset:), and then write another block, the data stored on disk is organized as follows:

ExpanDrive and File Provider Framework

Jason Snell:

Long-time Mac storage utility maker ExpanDrive has launched StrongSync, a $50 utility that… sort of does what ExpanDrive already does? Like its big brother, StrongSync allows you to view cloud storage services as if they were hard drives mounted on your Mac.


For storage providers the alternative to using kernel extensions is macOS Big Sur’s File Provider framework. This framework basically allows third-party apps to provide a bridge between the Mac’s filesystem and their cloud-storage providers of choice.


What this means for you: files get downloaded and open when you need them. They don't suck up any free space while not in use. It is fast as if it was local, because it's all on your SSD - not network drive or kernel extension. Strongsync support Sharepoint, OneDrive for Business, Google Drive and Google Workspace, Box with more clouds (Dropbox!) coming soon.

There’s also an S3 Pro app.


Monday, March 29, 2021 [Tweets] [Favorites]

How to Stop Mac App Store Notifications

Jeff Johnson:

Notifications Preferences lists apps in alphabetical order, but it’s missing A! Can you say App Store, kids?


Enter the following command.

defaults write LastUpdateNotification -date "2029-12-12 12:00:00 +0000"


PHP’s Git Server Compromised

Nikita Popov (via Hacker News):

Yesterday (2021-03-28) two malicious commits were pushed to the php-src repo from the names of Rasmus Lerdorf and myself. We don’t yet know how exactly this happened, but everything points towards a compromise of the server (rather than a compromise of an individual git account).

While investigation is still underway, we have decided that maintaining our own git infrastructure is an unnecessary security risk, and that we will discontinue the server. Instead, the repositories on GitHub, which were previously only mirrors, will become canonical.


Update (2021-04-07): Nikita Popov (via Hacker News):

We no longer believe the server has been compromised. However, it is possible that the user database leaked.

c0design Checker


Wrapper for codesign, spctl & stapler to check code signing and notarisation of individual or all non system applications.