Post

Replies

Boosts

Views

Activity

Documentation or Resources to Measure and Optimize SwiftUI Performance?
Does anyone have some resources to recommend for learning more about measuring and optimizing SwiftUI performance and rendering? I haven't seen a ton from Apple that looks like it's going to help me more. I did find two sessions from WWDC 2023. The "Demystify SwiftUI performance" session[1] does tell us the _printChanges function can help tell us when component bodies are computed. I see how I can attach this to a component that I built… I'm not (yet) sure if I have the ability to run this on arbitrary system components in my component graph. The "Analyze hangs with Instruments" session[2] does walk us through using the SwiftUI Instruments to measure body computations. Does anyone have any more resources along these lines for learning more? SwiftUI is closed source… so we don't really have easy visibility inside to see for ourselves. Bummer. Are there any additional debug APIs (like _printChanges) that can help for local development? I'm also interested to learn more about view equality[3]… I found this essay but it's four years old and I still can't find more information directly from Apple about EquatableView… I would prefer to find any more documentation or resources directly from Apple… but I would be happy with free third-party resources as long as they have some legit data to back up their code. Thanks! [1] https://developer.apple.com/videos/play/wwdc2023/10160/ [2] https://developer.apple.com/videos/play/wwdc2023/10248/ [3] https://swiftui-lab.com/equatableview/
0
0
513
Nov ’23
Can SwiftData Registered Models Be Equal Values and Different References?
Hi! I'm experimenting with SwiftData and looking for a situation where one persistentModelID might result in more than one registered model object reference delivered from a fetch from a single context. Here is an example of what I have to experiment: import Foundation import SwiftData @Model class Person { var name: String init(name: String) { self.name = name } } func main() { let configuration = ModelConfiguration( isStoredInMemoryOnly: true, allowsSave: true ) do { let container = try ModelContainer( for: Person.self, configurations: configuration ) let context = ModelContext(container) let person = Person(name: "John Appleseed") context.insert(person) let persistentModelID = person.persistentModelID if let left: Person = context.registeredModel(for: persistentModelID), let right: Person = context.registeredModel(for: persistentModelID) { print(left === right) // true } let descriptor = FetchDescriptor<Person>( predicate: #Predicate { person in person.persistentModelID == persistentModelID } ) if let left = try context.fetch(descriptor).last, let right = try context.fetch(descriptor).last { print(left === right) // true } } catch { print(error) } } main() This is a very simple command line app that attempts to fetch "two different" registered models… but both approaches (querying directly for persistentModelID and wrapping persistentModelID with FetchDescriptor) seem to consistently deliver objects equal by reference. Is there any situation where I could set this code up to deliver two registered models different by reference (but equal by value)? Is this anything I have to think about or manage at an "app" level? Is this behavior documented anywhere? Thanks!
0
0
865
Jan ’24
SwiftData Model fails to build from Xcode 15.4 when class access control is package?
Hi! I'm building an app from production Xcode_15.4.0 and I'm seeing strange behavior from the Model macro: import SwiftData @Model package class Person { init() { } } Building this from Xcode_15.4.0 or Swift 5.10 leads to these errors: /var/folders/1j/0r1s_v0n4bn200kt9nkm9j5w0000gn/T/swift-generated-sources/@__swiftmacro_9MyLibrary6Person5ModelfMe_.swift:1:1: error: initializer 'init(backingData:)' must be as accessible as its enclosing type because it matches a requirement in protocol 'PersistentModel' extension Person: SwiftData.PersistentModel { ^ /Users/rick/Desktop/MyLibrary/Sources/MyLibrary/MyLibrary.swift:3:1: note: in expansion of macro 'Model' on class 'Person' here @Model package class Person { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /var/folders/1j/0r1s_v0n4bn200kt9nkm9j5w0000gn/T/swift-generated-sources/@__swiftmacro_9MyLibrary6Person5ModelfMm_.swift:19:10: note: mark the initializer as 'package' to satisfy the requirement required init(backingData: any SwiftData.BackingData<Person>) { ^ /Users/rick/Desktop/MyLibrary/Sources/MyLibrary/MyLibrary.swift:3:1: note: in expansion of macro 'Model' on class 'Person' here @Model package class Person { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /var/folders/1j/0r1s_v0n4bn200kt9nkm9j5w0000gn/T/swift-generated-sources/@__swiftmacro_9MyLibrary6Person5ModelfMe_.swift:1:1: error: property 'schemaMetadata' must be as accessible as its enclosing type because it matches a requirement in protocol 'PersistentModel' extension Person: SwiftData.PersistentModel { ^ /Users/rick/Desktop/MyLibrary/Sources/MyLibrary/MyLibrary.swift:3:1: note: in expansion of macro 'Model' on class 'Person' here @Model package class Person { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /var/folders/1j/0r1s_v0n4bn200kt9nkm9j5w0000gn/T/swift-generated-sources/@__swiftmacro_9MyLibrary6Person5ModelfMm_.swift:13:12: note: mark the static property as 'package' to satisfy the requirement static var schemaMetadata: [SwiftData.Schema.PropertyMetadata] { ^ /Users/rick/Desktop/MyLibrary/Sources/MyLibrary/MyLibrary.swift:3:1: note: in expansion of macro 'Model' on class 'Person' here @Model package class Person { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /var/folders/1j/0r1s_v0n4bn200kt9nkm9j5w0000gn/T/swift-generated-sources/@__swiftmacro_9MyLibrary6Person5ModelfMe_.swift:1:1: error: initializer 'init(backingData:)' must be as accessible as its enclosing type because it matches a requirement in protocol 'PersistentModel' extension Person: SwiftData.PersistentModel { ^ /Users/rick/Desktop/MyLibrary/Sources/MyLibrary/MyLibrary.swift:3:1: note: in expansion of macro 'Model' on class 'Person' here @Model package class Person { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /var/folders/1j/0r1s_v0n4bn200kt9nkm9j5w0000gn/T/swift-generated-sources/@__swiftmacro_9MyLibrary6Person5ModelfMm_.swift:19:10: note: mark the initializer as 'package' to satisfy the requirement required init(backingData: any SwiftData.BackingData<Person>) { ^ /Users/rick/Desktop/MyLibrary/Sources/MyLibrary/MyLibrary.swift:3:1: note: in expansion of macro 'Model' on class 'Person' here @Model package class Person { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /var/folders/1j/0r1s_v0n4bn200kt9nkm9j5w0000gn/T/swift-generated-sources/@__swiftmacro_9MyLibrary6Person5ModelfMe_.swift:1:1: error: property 'schemaMetadata' must be as accessible as its enclosing type because it matches a requirement in protocol 'PersistentModel' extension Person: SwiftData.PersistentModel { ^ /Users/rick/Desktop/MyLibrary/Sources/MyLibrary/MyLibrary.swift:3:1: note: in expansion of macro 'Model' on class 'Person' here @Model package class Person { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /var/folders/1j/0r1s_v0n4bn200kt9nkm9j5w0000gn/T/swift-generated-sources/@__swiftmacro_9MyLibrary6Person5ModelfMm_.swift:13:12: note: mark the static property as 'package' to satisfy the requirement static var schemaMetadata: [SwiftData.Schema.PropertyMetadata] { ^ /Users/rick/Desktop/MyLibrary/Sources/MyLibrary/MyLibrary.swift:3:1: note: in expansion of macro 'Model' on class 'Person' here @Model package class Person { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: fatalError Building from Xcode_16_beta_4 or Swift 6.0 builds with no errors. Is this package issue being tracked for SwiftData when building from 5.10? It looks like this is fixed from 6.0… but I would like to build this code from production Swift today. Potential workarounds: Mark the class as internal or public? Use Xcode to inline the macro expansion and directly modify the broken functions with the correct access control? Any more ideas? My preference would be to keep this type package (while also building from 5.10). Any more workarounds (other than expanding the macro and modifying the functions myself by-hand)? Thanks!
0
0
354
Jul ’24
Is MapKit.mapCameraKeyframeAnimator broken on macOS 15.2?
Hi! I'm attempting to run the Quakes Sample App^1 from macOS. I am running breakpoints and confirming the mapCameraKeyframeAnimator is being called: .mapCameraKeyframeAnimator(trigger: selectedId) { initialCamera in let start = initialCamera.centerCoordinate let end = quakes[selectedId]?.location.coordinate ?? start let travelDistance = start.distance(to: end) let duration = max(min(travelDistance / 30, 5), 1) let finalAltitude = travelDistance > 20 ? 3_000_000 : min(initialCamera.distance, 3_000_000) let middleAltitude = finalAltitude * max(min(travelDistance / 5, 1.5), 1) KeyframeTrack(\MapCamera.centerCoordinate) { CubicKeyframe(end, duration: duration) } KeyframeTrack(\MapCamera.distance) { CubicKeyframe(middleAltitude, duration: duration / 2) CubicKeyframe(finalAltitude, duration: duration / 2) } } But I don't actually see any map animations taking place when that selection changes. Running the application from iPhone simulator does show the animations. I am building from Xcode Version 16.2 and macOS 15.2. Are there known issues with this API on macOS?
0
0
289
Dec ’24
Food Truck Sample animation issue from Table Component
Hi! I'm seeing some weird animation issues building the Food Truck sample application.^1 I'm running from macOS 15.4 and Xcode 16.3. I'm building the Food Truck application for macOS. I'm not focusing on iOS for now. The FoodTruckModel adds new Order values with an animation: // FoodTruckModel.swift withAnimation(.spring(response: 0.4, dampingFraction: 1)) { self.orders.append(orderGenerator.generateOrder(number: orders.count + 1, date: .now, generator: &generator)) } This then animates the OrdersTable when new Order values are added. Here is a small change to OrdersTable: // OrdersTable.swift - @State private var sortOrder = [KeyPathComparator(\Order.status, order: .reverse)] + @State private var sortOrder = [KeyPathComparator(\Order.creationDate, order: .reverse)] Running the app now inserts new Order values at the top. The problem is I seem to be seeing some weird animation issues here. It seems that as soon as the new Order comes in there is some kind of weird glitch where it appears as if part the animation is coming from the side instead of down from the top: What's then more weird is that if I seem to affect the state of the Table in any way then the next Order comes in with perfect animation. Scrolling the Table fixes the animation. Changing the creationData sort order from reverse to forward and back to reverse fixes the animation. Any ideas? Is there something about how the Food Truck product is built that would cause this to happen? Is this an underlying issue in the SwiftUI infra?
0
0
59
Apr ’25
Food-Truck-Sample navigation broken from Live Activity?
https://github.com/apple/sample-food-truck Hi! I'm seeing what looks like some weird navigation issue in the Food Truck app. It's from the Live Activity that should deep link to a specific point in the app. There seems be some state where the app is not linking to the correct component. Here are my repro steps on iPhone: Start live activity from OrderDetailView. Navigate to Sidebar component. Tap the Live Activity. App opens TruckView. The App should be opening the OrderDetailView for the Order that was passed to the Live Activity. This seems to work when the app is not currently on Sidebar. Any ideas? I'm testing this on iPhone OS 18.4.1. Is this an issue inside NavigationSplitView? Is this an issue with how Food Truck handles deeplinking?
0
0
61
May ’25