Archive for July 26, 2024

Friday, July 26, 2024

Stripe Acquires Lemon Squeezy

Lemon Squeezy Team (via Hacker News):

In 2020, when the world gave us lemons, we decided to make lemonade. We imagined a world where selling digital products would be as simple as opening a lemonade stand. We dreamed of a platform that would take the pain out of selling globally.

Tax headaches, fraud prevention, handling chargebacks, license key management, and file delivery, among other things, are complicated.

[…]

Going forward, our mission remains the same: make selling digital products easy-peasy.

With Stripe’s help, we’ll continue to improve the merchant of record offering, bolstering billing support, building an even more intuitive customer experience, and more.

Previously:

Update (2024-07-29): Patrick Collison:

Welcome @lmsqueezy! We’re going to scale merchant of record selling in a big way.

Sonos Apologizes for App Redesign

Marco.B:

Today we are introducing the most extensive app redesign ever, creating an unprecedented streaming experience that allows listeners to organize their favorite playlists, stations, albums and more from over 100 services on one customizable Home screen.

The new Home screen provides faster access to Sonos system controls with one easy swipe up, making tab to tab jumping a thing of the past. As a leader in sound experience that’s focused on creating a better way to listen, Sonos intentionally redesigned the app on a modern software platform for an easier, faster and better experience that can support more rapid innovation.

DianeRoberts (AMA):

The app is not exclusively built with Flutter, but does make use of Flutter for certain portions of the setup experience. We’ve actually been using Flutter for those experiences for many years, and ported that forward to the new app.

The majority of the app is in fact native. On iOS that means Swift, using SwiftUI. On Android that means Kotlin, using Jetpack Compose.

Juli Clover (forum threads):

Sonos this week released a major redesign for the Sonos app, introducing customizable home screen meant to deliver a personalized listening experience. The update was announced back in April, but just went live, and unfortunately, it removes a number of features while also introducing several bugs.

Multiple complaints on social media have called the app a “step back” with missing features like editing a song queue, managing playlists, shuffling a music library, and setting alarms and timers, along with slow performance and hard-to-access system controls. There has also been feedback from users about missing accessibility features.

The Verge asked Sonos about the negative feedback, and in response, Sonos said that it’s aware of the complaints, but “it takes courage” to rebuild a core product.

Juli Clover:

Sonos CEO Patrick Spence today penned a blog post on the Sonos website apologizing for the controversial Sonos app redesign and promising ongoing updates throughout the year.

Spence said that improving the app for customers is the company’s number one priority, and he explained that addressing bugs that came up in the new app delayed the introduction of additional features.

Previously:

Update (2024-08-01): Juli Clover:

Sonos community manager Keith Nieves confirmed the bug fix on Reddit (via The Verge), stating that the latest version of the app addresses an unspecified issue that was causing excessive battery use on some Apple devices. There have been several complaints about the app’s battery usage over the course of the last week, with the Sonos app running constantly in the background.

Unfortunately, several Reddit users have since said they’re having issues with the update, which seems to be causing a “No System Found” error message. This is a bug that existed previously, but the update seems to have increased the frequency of the error.

Update (2024-08-15): Chris Welch:

Sonos laid off approximately 100 employees this morning, a source familiar with the situation tells The Verge.

[…]

These latest cuts come as Sonos continues to grapple with the fallout from its disastrous mobile app redesign. On Sonos’ earnings call last week, CEO Patrick Spence stressed that fixing the app is the company’s number one priority — so much so that two hardware launches planned for later this year have now been delayed to keep all focus on the app.

Eric Slivka:

Just a few months after debuting an all-new mobile app for controlling its audio products, Sonos is considering bringing back the previous version of the app following numerous user complaints, reports The Verge.

Update (2024-08-21): Jay Peters (via Hacker News):

If you want the old Sonos app back, it’s not coming. In a Reddit AMA response posted Tuesday, Sonos CEO Spence says that he was hopeful “until very recently” that the company could rerelease the app, confirming a report from The Verge that the company was considering doing so. But after testing that option, rereleasing the old app would apparently make things worse, Spence says.

[…]

The trick of course is that Sonos is not just the mobile app, but software that runs on your speakers and in the cloud too. In the months since the new mobile app launched we’ve been updating the software that runs on our speakers and in the cloud to the point where today S2 is less reliable & less stable then what you remember.

Andy Pennell:

For the new app, Sonos threw out all of the old app code, a “clean slate” approach, replacing the front-end (the UX everyone loves to hate) and also the back-end (that actually communicates with speakers and music services).

[…]

When the app starts, it must find your speakers as a critical precursor to anything else, but for some inexplicable reason they decided to drop SSDP and rely entirely on mDNS for device discovery. I don’t know much about mDNS (as my own Sonos apps have never used it), but evidently this new way of finding speakers on the network has proven hugely problematic.

[…]

As all traffic is now encrypted, it takes more CPU cycles for every network call: client encrypts it, sends it (TLS is a lot more chatty), and the speakers have to decrypt it before they can do anything. The crypto overhead is going to be a challenge on the older Sonos devices, which have tiny amounts of RAM (as low as 64MB compared to 8GB of the latest Sonos devices) with a similar disparity in CPU power. Also the cloud API is more “chatty” than the UPnP API, multiplying the network overhead.

[…]

Another reason for the reduced performance is how music services now work: in the old app, the app made SMAPI calls directly to each music service (eg Apple, Spotify, etc), to enumerate items and get artwork. The new app instead calls into the Sonos cloud to do all of this, and then their cloud service makes the SMAPI calls to get the data (I assume), then it returns that data back to the app. Even for artwork! That’s a lot more networking traffic and a lot slower than before.

Eric Schwarz:

I don’t know what’s more infuriating—that a networked speaker manufacturer can’t seem to get networked speakers to work properly or that these require the cloud even for something as simple as AirPlaying content from within your own home network.

Update (2024-09-06): Ryan Christoffel:

Sonos has launched a public roadmap for its future. A new Trello board tracks fixes in the app and outlines what’s coming next.

denominator (via Hacker News):

In short, I’ll summarize my rant before story time - as a prior employee of Sonos, I believe that incompetence has infected top management at the company. Incompetence in management, incompetence in Software, SOFTWARE OH MY GOD this App roll-out, this roadmap.. is a joke.

HP Discontinues Online-Only LaserJet Printers

Sean Hollister:

Last May, I told you how HP’s bestselling printer can lock you to the company’s own subscription ink for life, with no way to cancel, with its dastardly HP Plus scheme. But HP has decided to remove those shackles from future laser printers, at least.

Christopher Harper (via Slashdot):

HP has finally been forced to discontinue its cheaper e-series LaserJet printers due to customers experiencing problems with their online-only and always tied to HP+ subscription requirements. Among other things, HP+ requires a permanent Internet connection, and customers only use HP-original ink and toners, not allowing for third-party alternatives to be used at all. There are benefits to HP+, including cloud printing and an extra year’s warranty, but the forced online requirement for a cheaper printer left a bad taste in the mouths of many consumers.

In any case, it’s important to clarify that this discontinuation of HP printers will only impact HP LaserJet printers that have an “e” added to the end of their model name to denote the alternative business model.

Previously:

SwiftData and Core Data at WWDC24

What’s new in SwiftData:

SwiftData makes it easy to add persistence to your app with its expressive, declarative API. Learn about refinements to SwiftData, including compound uniqueness constraints, faster queries with #Index, queries in Xcode previews, and rich predicate expressions. Join us to explore how you can use all of these features to express richer models and improve performance in your app.

[…]

You can use the new #Unique macro to tell SwiftData which combinations of your model’s properties must always remain unique in the model data. When two model instances share the same unique values, SwiftData will perform an upsert on collision with an existing model!

It seems there is still no way to control the merge policy.

New in iOS 18 is the ability to use Foundation’s new #Expression macro to build complex predicates easily! Expressions allow for reference values that do not produce true or false but instead allow for arbitrary types.

Create a custom data store with SwiftData:

Combine the power of SwiftData’s expressive, declarative modeling API with your own persistence backend. Learn how to build a custom data store and explore how to progressively add persistence features in your app.

Track model changes with SwiftData history:

Reveal the history of your model’s changes with SwiftData! Use the history API to understand when data store changes occurred, and learn how to use this information to build features like remote server sync and out-of-process change handing in your app. We’ll also cover how you can build support for the history API into a custom data store.

See also: the SwiftData documentation and updates.

I was not impressed with the introduction of SwiftData last year, and this year was also a disappointment. It seems like they are working on the wrong things and not communicating their vision for the future of SwiftData and how it will work with (or supplant) Core Data. It’s not clear whether this is a strategy and execution problem or primarily a communication problem, but it is leaving me unsettled.

Last year, SwiftData was very buggy and incomplete. This year, they didn’t talk about fixing the basics but rather about advanced and somewhat niche features like custom stores and history tracking. Last year, there was no integration between SwiftData and Core Data identifiers and predicates. There still seems to be none. The only mention of Core Data was that if you’re using Core Data’s persistent history you can now migrate to SwiftData history. There were no Core Data sessions at WWDC 2024.

So it remains unclear whether it’s even planned for SwiftData to be able to do the things that Core Data can. Is this going to be like SwiftUI where five years later they are still reimplementing features the previous framework has had for decades? It’s also unclear whether Core Data even has a future. Last year was encouraging in that both frameworks got equivalent new features at the same time. This year, Core Data got nothing, even though there’s a long list of outstanding feature requests, limitations, and bugs. Is this year an aberration? Or is Core Data in maintenance mode while they focus on SwiftData? It really does not feel good to have multiple apps and 20 years of code built on a framework that Apple isn’t talking about.

The point of building on system frameworks is that they’re in theory better supported than random open source projects. But now the future is uncertain, and it’s closed-source so that no one else can make the fixes or improvements that Apple won’t. I can’t rewrite my Core Data code in SwiftData because it’s so limited. Even if there are major improvements next year, they will be locked to macOS 16 and later, so it will be a long time before I can deploy code that uses them. At least right now, it’s not worth rewriting my code for a third-party framework. Core Data isn’t announced dead yet, and many other apps use it, so hopefully it’s safe to assume that Apple won’t let it break too badly. But if I were starting a new app today I would seriously consider whether it makes sense to be on the Apple train. There are some interesting alternatives such as GRDB, Lighter, and Blackbird.

Donny Wals:

It feels like Apple wanted to do more with SwiftData but they ran out of time. Surely being able to write your own persistence layer wasn’t the one thing they really wanted to ship, right?

There’s so much that developers were hoping for this year but we didn’t get any of it.

Makes me wonder whether the plan was to replace Core Data entirely and go from there but they couldn’t get it done so they gave us this instead?

Gwendal Roué:

I mostly see people hitting walls with SwiftData (limited support for non-optional relationships and ordered relationships, predicates that won’t compile, no dynamic predicate, change reactivity that does not work, etc.) And I’m all but charmed by its mutable model classes anyway. Maybe it would be interesting to have a GRDB store, so that one can workaround SwiftData limitations with a robust database API. But then, why not use the robust API in the first place?

Donny Wals:

Sadly, none of these limitations are the result of Core Data not supporting them. They’re a result of SwiftData’s interface not exposing these features. So even if you ship a custom persistence layer you’re limited by what SwiftData supports. And that’s not much.

For now, SwiftData remains a framework that’s only useful for small, simple apps that don’t need much in terms of features.

Fatbobman:

The latest version of SwiftData was surprisingly impactful. Although it might seem that few features were added on the surface, the substantial underlying adjustments were revolutionary. Considering that SwiftData was only founded a year ago, such changes were particularly unexpected. Stability remains a challenge, as seen in the first test version, which may disappoint many developers who had high expectations for SwiftData. However, after in-depth analysis, I believe there is sound reasoning behind these significant adjustments. The new version of SwiftData has almost achieved decoupling from the Apple ecosystem, and once it adds an independent default storage implementation, it will have all the makings of a cross-platform open-source framework. While this is just my personal hope, given Apple’s increasingly open approach to the community, the potential for this transformation is significant. If realized, the current waiting and effort will undoubtedly be worthwhile.

Helge Heß:

What they apparently didn’t do is fix the actual issues it had, like missing Observation refreshes 🙃

dasdom:

Is SwiftData dead already?

SENTINELITE:

I picked up SwiftData last year for my app, & it’s been an excruciatingly painful experience. Cloud syncing doesn’t always work, duplicate entries, etc.

Things didn’t really improve this year, although some internal things did, because some bugs have been cleaned up.

But… I just feel lost. I need the foundation of the app to be working, so I can dive into other APIs (Widgets, shortcuts, etc), but it’s been an uphill battle.

Helge Heß:

Something disappointing in SwiftData is that it doesn’t make use of the static nature of the macro(s). The macro can’t see the full schema like Lighter does, but it could still statically generate a ton, e.g. a static snapshot struct for the backing data. Or predefined indices for quickly binding the snapshot to the SQLite API (or really any).

Instead we get custom backends. Is anyone going to use this, for anything? Maybe they’ll eventually release it as FOSS for server side?

Helge Heß:

IMO the ability to replace the backend is exactly the wrong direction to go 🤷‍♀️ (for an embedded persistence framework). Specific backends should have specific implementations of the SwiftData API, not yet another layer in between that does abstractions which likely won’t fly. Remember the LDAP EOAdapter…

SENTINELITE:

Adopting SwiftData’s new History stuff, causes my model(s) to crash, as you can’t query embedded structs. […] I’m THIS close to rewriting the back-end. Gah.

Jon Duenas:

Yeah, it’s just, credit where credit is due, adding CloudKit to SwiftData “just worked”. With bugs and crashes, sure. But barely any extra effort on the developer’s end to do the actual syncing.

I’m actually considering whether I should just move rolling my own backend with something like Firebase or Supabase and make local storage more of a cache than the source of truth.

Duncan Babbage:

Would love any leads on this: setting [Core Data’s] .fetchBatchSize causes entire collection to be immediately traversed [by SwiftUI].

With Core Data and AppKit there are several possible solutions. If you fetch whole objects, the batching “just works,” so long as you stick to one store and avoid converting the NSArray to a Swift Array. With multiple stores, or to save memory, it’s straightforward to just fetch the sorted IDs and bring the objects into memory as needed.

Previously:

Update (2024-07-29): Helge Heß:

SQLite.swift is really slow. If you want a popular good one, rather get GRDB. Neither provides what SwiftData has though, i.e. an EditingContext.

I do think the context is a useful feature—another reason I’ve liked Core Data.

When I need direct SQLite access, I’ve been using SQLite.swift because it seemed simpler and smaller than GRDB. It like it, but it is indeed very slow due to Swift and GCD overhead within the framework. I was able to 3x the query performance by making some minor changes to reduce overhead and by manually unpacking the result rows. Now nearly all the time is spent in SQLite itself.

Update (2024-07-31): Keith Harrison:

First the bad news, this [SwiftData Indexes are] an iOS 18 feature that does not back deploy to iOS 17.

[…]

Note the subtle difference between adding an index for the individual properties or a compound index (I can see myself getting this wrong)[…]

I don’t see how to index the entity column.