Monday, November 4, 2019

Electron Apps Rejected From the Mac App Store

David.dev (via Ben Sandofsky, Hacker News, Slashdot):

Allright, as a follow up to the previous chapter in this odyssey I can now state that, apparently,  you cannot submit an electron 6 or 7 app to the apple store:

The first refusal from apple states:

Your app app links against the following non-public framework(s):
CAContext
CALayerHost
NSAccessibilityRemoteUIElement
NSNextStepFrame
NSThemeFrame
NSURLFileTypeMappings

I am not the only one having this issue and I did write back to Apple trying to explain that I am using Electron and I can’t really change any of these public-framework usage (I assume is something from Chromium)[…]

Craig Hockenberry:

There was a time when digging into the bowels of the macOS implementation was “necessary”. Back in the day, you’d use NSThemeFrame to get UI into an app’s titlebar.

iTunes did it, so everyone wanted to do it.

But those days are long gone - there are public APIs to get the job done now.

And with the advent of Spaces, split-screen windows, and translucent effects, using these private APIs are likely to break an app.

Unfortunately, that isn’t the whole story. Some of the private APIs are used in the Web rendering engine itself:

Mozilla recently published a good write up on why they started using the undocumented CALayer API in Firefox 69. The TLDR is that that these private API’s allowed them to get up to 3x better battery usage in Firefox. The article also mentioned that Chrome uses these Core Animation API’s.

So there are a multiple problems here:

  1. It’s (apparently) impossible for Chromium to get competitive performance and battery life without using private API, which Safari freely uses.
  2. Apple probably has good reasons for keeping these APIs private.
  3. Private API has always been banned, but Apple has been accepting these apps for years and then abruptly stopped without any notice.
  4. Apps using Electron probably didn’t know that they were even using private API. Neither Xcode nor Application Loader reports this, and App Review was accepting the apps.
  5. The rule is not being enforced equally.

Jeff Johnson:

I just checked Slack, which was updated 3 days ago, and its embedded Electron Framework contains all of the listed private symbols.

“And developers, from first-time engineers to larger companies, can rest assured that everyone is playing by the same set of rules.”

thomascgalvin:

This, however, is draconian:

Continuing to use or conceal non-public APIs in future submissions of this app may result in the termination of your Apple Developer account, as well as removal of all associated apps from the App Store.

“Keep trying to submit, and we might just ban you forever” is insane. Every program of any complexity depends on third party libraries, and many people wouldn’t be able to tell what arcane APIs their dependencies (or their dependencies’ dependencies) call. “If you continue to have an upstream dependency that violates our terms, we might permaban you” is bullshit.

Colin Cornaby:

This has got to be a big problem for Apple. The widespread distribution of Electron and Chromium means they have to maintain this as semi-public API. Or risk breaking a lot of apps in a future OS release. Google is forcing them into a bad spot.

Matt Birchler:

Good people of Twitter, what are your favorite Catalyst apps? Asking because I am yet to find one that is remotely as good as the Electron apps I use daily.

I’ll be more specific: Slack and Visual Studio Code works great for me, while Postman is a little annoying, but very functional. Meanwhile the Jira and Twitter Catalyst apps have sent me running back for the web.

Previously:

Update (2019-11-05): anatomisation points out that the Mozilla post does not actually say that they are using private API and that WebKit is not using CALayerHost very extensively. However, Chromium does seem to be using it for compositing during rendering.

Pierre Lebeaupin:

Reminds me of the time people found out Unity was relying on an undocumented API, around the iPhoneOS 3 or iOS 4 timeframe IIRC. I think we were affected too (by direct usage, not through Unity. Our bad.

Jeff Johnson:

These private symbols have been in Electron/Chromium for a long time. Strange coincidence that Apple is changing their enforcement now, so soon after Catalyst is available.

[…]

That neither Chrome nor Firefox is in the MAS could be considered an indictment of the MAS.

Previously:

Rosyna Keller:

FWIW, Chromium is using CALayerHost for something better served by public IOSurface APIs and public CALayer properties.

Update (2019-11-09): Owen Williams (via Hacker News):

Developers use technologies like Electron and PWA because they allow for faster updates across platforms without an array of different codebases. Some argue that this results in lower quality apps, but I’d argue the alternative is no app at all or apps that are rarely updated because maintaining unique Windows, Mac, and web-based products is complex and expensive.

[…]

Apple’s subtle, anti-competitive practices don’t look terrible in isolation, but together they form a clear strategy: Make it so painful to build with web-based technology on Apple platforms that developers won’t bother.

[…]

These types of changes may be made in the name of privacy or security, but the reality is that the argument looks weak when both users and developers simply don’t have a choice because Apple controls the platform, browser engine, and the distribution method. Regardless of your opinion of Electron app quality, choice is important.

Update (2019-12-17): Jeff Johnson:

Slack was updated again today in the Mac App Store, and guess what? The private symbols are still there.

15 Comments RSS · Twitter

Maybe this will force Slack to finally think about writing a bloody native app? One can hope.

> Maybe this will force Slack to finally think about writing a bloody native app? One can hope.

That seems deeply unlikely to me unless they plan to write native Windows, Mac, and Linux apps as well as maintaining their web app. The best bet for "native" is a catalyst app, but that's not much better at this point. Maybe in a few years when Catalyst has matured.

There’s a new/nascent effort called NodeGUI that tries to do something similar to Electron, but renders to Qt under the hood instead of HTML: https://github.com/nodegui/react-nodegui

I wonder if it’ll get additional traction because of these App Store rules suddenly being enforced.

> Maybe this will force Slack to finally think about writing a bloody native app? One can hope.

+1

>Maybe this will force Slack to finally think about writing a bloody native app?

I wonder how much negative feedback they actually get about the fact that their app is built on Electron, or about Electron-related issues in the app. I bet most people couldn't possibly care less.

> Mozilla recently published a good write up on why they started using the undocumented CALayer API in Firefox 69. The TLDR is that that these private API’s allowed them to get up to 3x better battery usage in Firefox. The article also mentioned that Chrome uses these Core Animation API’s.

Mozilla did no such thing. The very blogpost linked says they use IOSurface as CALayer.contents. That's not private API. Check out Firefox 69 for yourself, there's no reference to CALayerHost.

I'm used to this community spreading FUD, but it never gets less disappointing.

@Zachary The Mozilla post says it’s about Firefox 70 (despite what the Electron GitHub comment says).

Robert Watkins

There's no references to CALayerHost in Firefox 70 either

@Robert Thanks for checking. I don’t know what the basis for humphrey’s claim is. Perhaps he was referring to other undocumented API or was just mistaken.

The blog post says "It’s worth noting that the ability to assign an IOSurface to the CALayer contents property is not properly documented." Not properly documented != private API.

Steven Fisher

I wonder if intermittent enforcement on particular private symbols has anything to do with the new hardened runtime options.

Well, if you include a dependency, it becomes your responsibility. That is one of the key risks of using 3rd party code, and even if Apple might have overlooked that for a while, there is no guarantee that they don't change their policy at any given moment.

It's not *their* semi-public API, and there is really no reason they should let impose others constraints on their private APIs. It's very well possible that they plan to deprecate the APIs in question, and therefore have introduced these checks lately.

That said, it would be much better policy by Apple to introduce new checks for private APIs on the warning level first (for a couple of weeks at least), before simply rejecting.

>Well, if you include a dependency, it becomes your responsibility.
>That is one of the key risks of using 3rd party code, and even if
>Apple might have overlooked that for a while, there is no guarantee
>that they don't change their policy at any given moment.

I guess that's technically true, but the reality is that there is probably no non-trivial application out there that doesn't include at least some third-party dependencies. This includes pretty much all games. If Apple can't find a way to deal with this reality without seemingly randomly rejecting apps, then it shouldn't be a surprise that there is a clear lack of willingness to invest into high-quality applications for Apple's platforms.

In other words, if there's anyways a chance that Apple will suddenly reject my app, it makes much more sense to just publish an existing Electron app on Apple's platform instead of investing money into building something custom, since this limits the cost of rejection.

As a nice side-effect, this also externalizes my cost of fixing any of the problems Apple causes. If I have to use a private API to get something to work, it's my problem if Apple rejects me. If I use Electron, it's somebody else's problem, and I just have to wait for an update to Electron.

[…] looks like Apple started rejecting applications build using Electron in the AppStore review process. Chromium, the foundation of Electron, is using private APIs, […]

Leave a Comment