Archive for May 28, 2024

Tuesday, May 28, 2024

iPhones Pause Charging During Continuity Camera

Adam Engst:

Apple seems allergic to saying that an iPhone won’t charge with MagSafe during Continuity Camera. However, it may not charge over USB either. Several users in a Reddit conversation reported that their iPhones lost charge during Continuity Camera sessions, even while plugged in.

I suspect that Continuity Camera taxes the processor sufficiently that the iPhone heats up. (It’s always warm when I take it off the mount after a meeting.) Since MagSafe charging also causes the iPhone to get warm—warmer than USB-based charging—Apple’s battery optimization system may be putting charging on hold to protect the battery from thermal overload. Which is good, if unexpected in the moment.

The practical upshot is that if you use Continuity Camera, you should expect your iPhone’s battery to drop, potentially significantly.

Dynamic Swift Predicates in macOS 14 and iOS 17

Helge Heß:

The new Foundation/#Swiftlang Predicates (and its expressions) seem a little weird because they can’t be constructed dynamically?

Fly0strich:

However, when I try to use that method inside of a #Predicate closure, it gives an error saying that the method is not supported by this predicate.

Debbie Goldsmith:

If you want to construct a Predicate dynamically, you need to build it up from PredicateExpression pieces rather than use the #Predicate macro (similar to building an NSPredicate from NSExpression). Expand the macro in Xcode and you can see how the pieces are put together.

It’s a lot more complicated than NSPredicate due to the static typing, and there’s no way to convert between the two types if you’re using both Core Data and SwiftData.

Fatbobman:

NSCompoundPredicate allows developers to combine multiple NSPredicate objects into a single compound predicate. This mechanism is particularly suited for scenarios that require data filtering based on multiple criteria. However, in the new Foundation framework restructured with Swift, the direct functionality corresponding to NSCompoundPredicate is missing. This change poses a significant challenge for developers who wish to build applications using SwiftData. This article aims to explore how to dynamically construct complex predicates that meet the requirements of SwiftData, utilizing PredicateExpression, under the current technical conditions.

[…]

The issue lies in the expression property being of the type any StandardPredicateExpression<Bool>, which doesn’t contain sufficient information to identify the specific PredicateExpression implementation type. Since Conjunction requires the exact types of the left and right sub-expressions for initialization, we are unable to use the expression property directly to dynamically construct new combined expressions.

[…]

Although we cannot directly utilize the expression attribute of Swift Predicate, there are still alternative ways to achieve the goal of dynamically constructing predicates. The key lies in understanding how to extract or independently create expressions from existing predicates and utilize expression builders such as build_Conjunction or build_Disjunction to generate new predicate expressions.

Jeremy Schonfeld:

If you need to dynamically create a predicate while analyzing what should go into the predicate, you can do so by manually constructing the expression tree. Unfortunately, since this is a more advanced use case you wouldn't be able to use the macro to help here, but you could write something along the lines of the following[…]

[…]

In short, we create a list of the conditions that need to be met and build up the list based on which parameters are specified to the makePredicate function. We can then reduce this array into a single tree of conjunctions to ensure that all of the conditions are met. There are a few small hoops to jump through here in order to satisfy the type-checker with the use of generics such as the closure and separate buildConjunction function, but this allows you to just append to conditions for each new property rather than needing to work with a combinatorial explosion of conditions using the macro.

Noah Kamara:

CompoundPredicate aims to improve the Predicate system to enable combining multiple predicates after constructing them[…]

This looks like a huge improvement. It’s not clear to me whether there are still limitations compared with NSPredicate.

Fatbobman:

This new strategy abandons the previous reliance on a custom StandardPredicateExpression implementation, opting instead for a type-casting strategy that effectively concretizes the information of expression. This improvement means developers can avoid the cumbersome process of manually extracting and combining expressions.

[…]

This method enables the automatic acquisition of the exact type of expressions inside the Predicate during the predicate combination process, facilitating an automated and efficient combination of predicates.

Helge Heß:

You know how Foundation (in part to support SwiftData) now has the Predicate macro? Well, RealityKit has its own generic QueryPredicate And guess what, they don’t need a macro to build them, looks like overloading the operators || and && is fine there.

Debbie Goldsmith:

Operator overloads not only cause longer build times for Predicate, but for other uses of that operator.

But even with macros:

In this example, even minor code changes can cause the compilation time for this file to exceed 10 seconds. This delay can also occur when generating expressions using closures.

Andy Finnell:

Using generics to create SwiftData Predicates leads to crashy times.

[…]

FYI, I solved this by writing another macro.

This is my new mantra: code not working? You don't have enough macros.

Jeremy Schonfeld:

Since Predicate is both Codable and Sendable, it requires that everything the predicate captures (i.e. all instances captured by the closure) are also Codable and Sendable.

Previously: