Archive for December 16, 2022

Friday, December 16, 2022

Sunsetting AppCode

Anastasia Kazakova (Hacker News):

Since the release of AppCode 1.0 11 years ago, we’ve been applying our expertise to make coding for iOS/macOS more enjoyable. We’ve had many accomplishments, including first-class C++ support (from which CLion, our cross-platform C/C++ IDE, was born), an extremely fast release of initial support for the new Swift language, and finally, Kotlin Multiplatform Mobile technology, which combines our passion for Kotlin with our knowledge of mobile technologies.

While we’ve had some growth in terms of adoption, we didn’t reach the market share we had hoped for. We believe that the time has come to sunset the product and focus our efforts in other directions.

Jacob Gorban:

I’ve used this IDE on and off for many years. It’s got so much stuff that put it way beyond Xcode. At the same time, it was also lagging in some respect, and Apple’s speed of change with its tooling was probably hard to keep up with.

Dave Verwer:

Some people will dearly miss it but never quite made it big enough in the Swift development community to become mainstream. It got close, though, especially a couple of years after it first launched.

Competition in this area is a good thing, but with Xcode being so good and VS Code’s support for Swift getting better every day, it’s an extremely tough market to enter with a paid product.

The reasons behind subsetting AppCode make sense, but the Swift tools ecosystem will be poorer without it.


SuperDuper 3.7.1

Dave Nanian:

In Ventura, on some systems, we’ve seen some cases where, post-replication (“Erase, then copy” in Big Sur and later), the destination volumes wouldn’t always re-mount. Sometimes an error would occur (referencing the ‘bsd’ info), sometimes not. When these failures occur, Apple’s replicator has also replicated the source volume name, and due to the error, we didn’t get a chance to rename it back to what’s expected.

Anyway, it was annoying to you and (because we hate things like this) us. So we’ve been working for the last month or so to try to find a way to fix this…and I’m happy to say we have.


We’ve found the key needed to get the startup items to say something more sensible, and so now they’ll say “SuperDuper!”—please don’t turn them off! If you do, your schedules will not work.


Publishing an RSS Feed to Mastodon

Jesse Squires:

If you follow me on Twitter, you’ve likely noticed that my blog posts are automatically tweeted for me. There are multiple services you can use to do this, like Zapier and IFTTT. I use both services for various automations. Each has built-in actions for listening to an RSS feed and then tweeting new items as they appear. Sadly, neither service has a built-in action for Mastodon. However, we can achieve the same results with a generic webhook action on both platforms.

Proton Drive

Andy Yen:

Proton Drive’s mobile apps give you the freedom to access your files and folders from anywhere, anytime. You can upload your files and photos to Proton Drive using your mobile app and access them either on your mobile device or on your laptop or desktop by logging in to the Proton Drive web app. Your files will be available seamlessly on all devices and platforms.

Even in today’s constantly connected world, there are places with weak or no mobile network coverage. Our iPhone, iPad, and Android apps solve this problem by giving you offline access to your files and folders so you can access them without an internet connection. If you activate offline access for a file or folder, they’ll be encrypted and saved on your device so that they can only be accessed through the Proton Drive app. This gives you constant access to your files without compromising their security.


Your files are encrypted on your mobile device using encryption keys you control, and best of all, this encryption happens automatically without requiring any action from you.

The Mac and Windows versions are not in beta yet.

Tim Hardwick:

Proton Drive offers a free version with 1GB of cloud storage, while users subscribing to 500GB of encrypted storage ($9.99/month) via the Proton Unlimited plan also get Proton Mail, Proton Calendar, and Proton VPN. There’s also an individual Proton Drive subscription that offers 200GB of storage for $3.99 a month.


Update (2023-03-03): Anant Vijay:

We’re excited to announce that we’ve open-sourced the Proton Drive Android and iOS apps’ code. This means the code for all Proton apps out of beta, including all Proton Drive apps, is now available for anyone to examine. You can verify for yourself that these are doing exactly what we claim.

Update (2023-05-16): Anant Vijay:

If you’re on a Free plan, Proton Drive will store older versions of files for up to seven days. If you’re on a paid plan, you can access versions of your files that are up to 10 years old.

Swift Pitch: Observation

Philippe Hausler:

There are already a few mechanisms for observation in Swift. Some of these include Key Value Observing (KVO), or ObservableObject; but those are relegated to in the case of KVO to just NSObject descendants, and ObservableObject requires using Combine which is restricted to Darwin platforms and does not leverage language features like async/await or AsyncSequence. By taking experience from those existing systems we can build a more generally useful feature that applies to all Swift reference types; not just those that inherit from NSObject and have it work cross platform with using the advantages from low level language features like async/await.


Combine’s ObservableObject produces changes on the leading edge of the will/did events and all delivered values are before the value did set. Albeit this serves SwiftUI well, it is restrictive for non SwiftUI usage and can be surprising to developers first encountering that restriction.


The Observable protocol includes a set of extension methods to handle observation. In the simplest, most common case, a client can use the changes(for:) method to observe changes to that field for a given instance. […] This allows users of this protocol to be able to observe the changes to specific values either as a distinct step in the chain of change events or as an asynchronous sequence of change events.


By default the concept of observation is transitively forwarded; observing a keypath of \A.b.c.d means that if the field .b is Observable that is registered with an observer to track \B.c.d and so on. This means that graphs of observations can be tracked such that any set of changes are forwarded as an event.


The ObservationTracking mechanism is the primary interface designed for the purposes to interoperate with SwiftUI. Views will register via the withTracking method such that if in the execution of body any field is accessed in an Observable that field is registered into the access set that will be indicated in the handler passed to the addChangeHandler function. If at any point in time that handler needs to be directly invalidated the invalidate function can be invoked; which will remove all change handlers registered to the Observable instances under the tracking.


A default implementation can be accomplished in generality by a type wrapper that intercepts the modifications of any field on the Observable . The type wrapper DefaultObservable provides default implementations for the type where the associated Observation type is ObservationTracking.Token. This means that developers have the flexibility of an easy to use interface that progressively allows for more and more detailed control: starting from mere annotation that grants general observability, progressing to delegation to a storage mechanism that manages registering and unregistering observers, to full control of observation.

David Smith:

There’s a number of issues we ran into with KVO, all around concurrency[…]

David Smith:

Philippe’s new ObservationTracking machinery reads like a shippable spiritual successor to that hack.

Update (2023-03-20): Philippe Hausler:

  • Pitch 1: Initial pitch
  • Pitch 2: Previously Observation registered observers directly to Observable, the new approach registers observers to an Observable via a ObservationTransactionModel. These models control the “edge” of where the change is emitted. They are the responsible component for notifying the observers of events. This allows the observers to focus on just the event and not worry about “leading” or “trailing” (will/did) “edges” of the signal. Additionally the pitch was shifted from the type wrapper feature over to the more appropriate macro features.
  • Pitch 3: The Observer protocol and addObserver(_:) method are gone in favor of providing async sequences of changes and transactions.

Update (2023-04-21): Ben Cohen:

The review of SE-0395: Observability begins now and runs through April 24, 2023.

UNAlertStyle Restricted

Patrick Wardle:

If a tool notifies the user via macOS’s notification center the style can no longer be programmatically set to alert …only banner.

Banners are automatically dismissed which breaks security alert requiring user interaction! 🥲

Note: Apple’s apps can send alerts by default 🤪

It’s frustrating how API limitations like this tend not to get announced or documented.

Thomas Reed:

I’ve always argued against a custom alert pop-up implementation in Malwarebytes for Mac, favoring native notifications instead. But if the user can now miss an important alert about an infection, that’s going to change the equation. 😕

C xor C++ Programming

Aaron Ballman (PDF via John Regehr, Steve Canon):

It is not uncommon to hear about C/C++ programming as a shorthand for “C and C++” programming. This implies that C and C++ are similar, but distinct, programming languages with the obvious interpretation being that C++ is a proper superset of C. However, this does not accurately describe the situation. The C++ programming language is inspired by the C programming language and supports much of the syntax and semantics of C, but is not a superset that is built on top of C. Despite sharing a historical relationship to one another, the languages have evolved independently and are specified in separate language standards. Due to this separation of the two specifications, incompatibilities have crept into the shared space of code that can be compiled by either a C compiler or a C++ compiler.

This document enumerates instances where the same source code has different meaning when compiled with C and C++ implementations. Such source code is often a pain point for users and implementers because it represents a “sharp edge” in both languages, especially if the code appears in a header file that may be compiled in separate C and C++ translation units.