Archive for November 25, 2020

Wednesday, November 25, 2020

iOS Apps Not Available in the Mac App Store

Jason Snell:

If there’s a single disappointment in the release of Apple’s first wave of M1 Macs, it’s the lackluster launch of iOS apps running inside of macOS. What should be an amazing unification of Apple’s platforms and a massive expansion of the Mac software base is, instead… kind of a non-event.

Running iOS apps on the Mac can be a little weird, it’s true. But it can sometimes be good. Unfortunately, a lot of interesting iOS apps just aren’t available at all, because their developers have removed them from the Mac side of the iOS App Store.


But Apple’s biggest impact can come with the decisions it makes about hardware. The reason some iOS apps feel weird on the Mac is that they were designed for touch, not for a cursor and keyboard. Introducing Macs with touchscreens won’t change the Mac’s status as a mouse-first operating system, but it will offer alternate modes of input—and open up better compatibility with some iOS apps.

Juli Clover:

App developers can choose not to make their iPhone and iPad apps available on M1 Macs through the Mac App Store, and many popular apps like Netflix, Hulu, and others have made this choice. There is a workaround for installing these apps anyway, but it involves third-party software.

As it turns out, the M1 Macs are able to run any .ipa file, which is the format used for iOS apps. You need the .ipa file for an app to run it on an M1 Mac, and getting those files can be done through software like iMazing.


There is an alternative method that uses Apple’s free Apple Configurator 2 app, but does require you to use the Terminal to fix permissions. The instructions are detailed in this forum post.

Michael Love:

Man Apple screwed this up - “opt out of distributing your iOS app on Mac” except not really because anybody can run it without even modifying the binary (and without FairPlay).

Apple has pretty much ignored the issue of how to validate purchases. This could have been an advantage of the Mac App Store, with the system handling it automatically like on iOS. Instead, we got nine years of buggy sample code for receipt validation. And now no protections for apps that opt out of Mac support.


Update (2021-01-14): Filipe Espósito (via Michael Love):

Based on internal code that is shared between recent iOS 14.4 beta versions and macOS Big Sur 11.2, Apple is implementing a new system that will block some iOS apps from running on the Mac. This, of course, will not affect the apps available on the Mac App Store.

Instead, this should prevent users from installing iOS apps that the developer has chosen not to offer on the Mac App Store for M1 Macs.


Update: At least for now, macOS Big Sur 11.1 beta 2 still lets users sideload unsupported iOS apps on M1 Macs.

Update (2021-01-15): Chance Miller (tweet):

Earlier this week, 9to5Mac reported that Apple would soon start blocking users from side loading iPhone and iPad applications to their M1 Macs. Now, Apple has officially flipped the server-side switch to implement this change.

Update (2021-01-19): Chance Miller:

Interestingly, Apple has reverted the server-side change that blocked users from side loading iPhone and iPad apps to their M1 Mac.

So for now, you can keep side loading iPhone and iPad apps to your M1 Mac, but we don’t expect it to last.

libdispatch’s Unmet Promise

Thomas Clement:

Apple demonstrated the libdispatch and the promise seemed great, they introduced the notion of serial queues and told us that we should stop thinking in term of threads and start thinking in term of queues. We would submit various program tasks to be executed serially or concurrently and the libdispatch would do the rest, automatically scaling based on the available hardware. Queues were cheap, we could have a lot of them. I actually remember very vividly a Q&A at the end of one of the WWDC sessions, a developer got to the mic and asked how many queues we could have in a program, how cheap were they really? The Apple engineer on stage answered that most of the queue size was basically the debug label that the developer would pass to it at creation time. We could have thousands of them without a problem.


Then the problems started. We ran into thread explosion which was really surprising because we were told that the libdispatch would automatically scale based on the available hardware so we expected the number of threads to more or less match the number of cores in the machine. A younger me in 2010 asked for help on the libdispatch mailing-list and the response from Apple at the time was to remove synchronization points and go async all the way.

As we went down that rabbit hole, things got progressively worse. Async functions have the bad habit of contaminating other functions: because a function can’t call another async function and return a result without being async itself, entire chain calls had to be turned async.


Turns out Apple engineers are developers just like us and met the exact same problems that we did. […] An Apple engineer also revealed that a lot of the perf wins in iOS 12 were from daemons going single-threaded.


Now I’m a bit worried because I see all those shiny new things that Apple is planning to add into the Swift language and I wonder what might happen this time.

Via Peter Steinberger:

Please see past the clickbaity title. It failed to deliver on the promise. It’s still incredibly useful. It’s just dangerous that the documentation wasn’t updated to reflect this.

Greg Titus:

To call any technology a failure because it was initially over-promised would leave pretty much no successes ever.

Coding under Dispatch is a lot nicer than pthreads or NSThread/NSLock, which were the options on the platform before its debut. By my definition that’d be success.

Alexis Gallagher:

P1. Task queues will be easier than threads & locks.

P2. libdispatch can handle many queues and it is sensible to organize a program that way.

Could be we agree that P1 was true but P2 proved false for a mix of performance and programming model complexity reasons.

Jonathan Grynspan:

I say: dispatch long-running (like, seconds or more) tasks off the UI thread, including as much I/O as possible. Everything else can run on one thread. Other processes can use other cores. Enforce in API by making most stuff sync but long tasks async with a completion handler.

David Smith:

Personally I currently prefer a small number of queues (or workloops!) for execution contexts and unfair locks for protecting state. For example cfprefsd uses* a two queue model (“request processing” and “async IO” queues), but fine grained locking.

Marcel Weiher (quoting his excellent iOS and macOS Performance Tuning):

Due to the pretty amazing single-core performance of today’s CPUs, it turns out that the vast majority of CPU performance problems are not, in fact, due to limits of the CPU, but rather due to sub-optimal program organization

In the end, I’ve rarely had to use multi-threading for speeding up a CPU-bound task in anger, and chances are good that I would have made my code slower rather than faster. The advice to never optimize without measuring as you go along goes double for multi-threading.


Update (2020-11-30): David Zarzycki:

As the designer of libdispatch, I just want to say: I get why people feel this way and I’m sorry that we/I oversold libdispatch to some degree at the time.

(And just to be clear, I left Apple many years ago and I still deeply respect them.)

I also feel bad because I knew that blocking was a pain point and I had plans/ideas for how to minimize that pain but I burned out after GCD 1.0 and took a leave of absence. I don’t think those ideas ever got recorded or implemented. So ya, I’m sorry about that too.

That being said, what we had before libdispatch was awful. POSIX and derived threading APIs are both more difficult to use and more inefficient. I do feel proud that we made life easier for people in this regard and helped people clean up their existing threading code.

Chris Nebel:

Maybe you can clear something up for me: these days, we’re advised to not use concurrent queues, because the system will start a thread for every block in the queue because it has no idea which blocks depend on which others to make progress. Fair enough, but as I recall the initial presentations, concurrent queues only promised some amount of concurrency, where “some” might be “none”, meaning that if you deadlocked a concurrent queue, it would be your fault, not the system’s. Did something change, or am I misremembering?

Pierre Habouzit:

that’s how one was told they worked, but never did. if a work item blocks on a concurrent queue, you get more threads eventually.

We now recognize some blocking situations as being due to contention and excluded such blocking points from the policy, but it only goes so far.

the other problem is that the concurrent queue pool (non overcommit threads in the implementation parlance) are a shared singleton which makes using them correctly fraught with peril if you allow blocking on future work.

This is why Swift Actors executors have to disallow it.

David Zarzycki:

The overcommit queues were never supposed to exist. They were added as attempt to fix a bug on the single core Mac mini but later we found the root cause: workqueue threads defaulted to SCHED_FIFO instead of SCHED_OTHER and it was too late to remove overcommit queues before GM

Update (2020-12-24): Brent Simmons (tweet):

We’ve been getting some reports that NetNewsWire for Mac will hang sometimes. A sample will report something like this[…] And there will be hundreds of threads labelled

ML Compute on M1 Macs


Until now, TensorFlow has only utilized the CPU for training on Mac. The new tensorflow_macos fork of TensorFlow 2.4 leverages ML Compute to enable machine learning libraries to take full advantage of not only the CPU, but also the GPU in both M1- and Intel-powered Macs for dramatically faster training performance.


Performance benchmarks for Mac-optimized TensorFlow training show significant speedups for common models across M1- and Intel-powered Macs when leveraging the GPU for training. For example, TensorFlow users can now get up to 7x faster training on the new 13-inch MacBook Pro with M1[…]


Hazel 5

Alex Guyot:

Hazel is a classic Mac automation tool which we last covered several years ago for version 4. This week Hazel is back with version 5, a major update which brings the tool out of System Preferences for the first time.


Hazel 5’s interface combines the folders and rules views into a single multi-column layout. This change makes the app much more fluid to navigate, and the new ability to group folders makes organization far nicer as well. While editing rules you can now detach the editor view from the main window, making side-by-side editing of multiple rules possible for the first time.

Update (2020-12-09): Paul Kim:

The most obvious thing you’ll probably notice is that Hazel is no longer a preference pane, instead shipping in an app form factor. Why? The main reason is Apple. If you missed my post on this topic, in short, Apple screwed over preference panes in Catalina. The result is a buggy mess and I’ve seen almost no improvement on that front since then. It seemed clear to me that preference panes were a developmental dead end.

I had already been planning on releasing a version 5 so I was prepared to make some major changes. Problem was, I had to make sure I released 5.0 around when Apple’s next OS (now known as Big Sur) would arrive. Why? Because any Big Sur compatibility work put into Hazel 4 would most likely not be usable in version 5. Partly because of the major changes between the two but mostly because many of the issues that affect preference panes since Catalina aren’t a problem for apps. I could either do double the work or cut my losses and do a big push for version 5 in the time available. The downside is that the conversion to an app displaced other features I had planned. Some of these will make it into point releases but the bigger ones may have to wait until 6.0.

See also: Hazel 5.0 Release Notes.


Update (2021-01-04): Paul Kim:

As promised, I thought I’d write about my launch. While not disastrous, it had its share of bumps. I had hoped that I had learned something from the Hazel 4 launch four years ago. One of the issues was server capacity.


Hazel is codesigned and notarized yet on some people’s systems, it would reject Hazel, either wholesale or in parts.


As for the issue, it seems that 10.13 has problems with certain named/system colors when the app is linked against 11.0. Solution was to do special-case code for 10.13 using non-named colors.


And with all of the above issues, I had to deal with thousands of people reporting them. Especially in the first few days, it was a frantic balancing act of being responsive to users while trying to carve out time to investigate the issues they were reporting.


Oddly, I found that the press was noticeably absent. It seems that even though the Mac market keeps growing, there are fewer and fewer outlets reporting and reviewing Mac products. Hazel has enough of a following that it didn’t matter as much but it feels as if things have regressed on that front, which is a bit sad.