Post

Replies

Boosts

Views

Activity

Reply to `SwiftUI.Table` Select and Done buttons breaking navigation on iPadOS?
If the find a bug in the sample code please file a big report via Feedback Assistant and post the FB number here once you do. https://appleinsider.com/articles/25/04/18/when-you-report-bugs-on-ios-some-content-may-be-used-for-ai-training Thanks… but for privacy reasons I'm currently blocked on submitting bug reports due to a requirement on AI training. Are you referring to the dismiss environment property? I'm referring to the Select and Done buttons that appear to toggle EditMode:
Topic: UI Frameworks SubTopic: SwiftUI Tags:
May ’25
Reply to LiveActivities preview in XCode, Missing 'previewContext'
https://github.com/apple/sample-food-truck/blob/3954a769e99f3cc53297d94f2b960ceb2665b3d6/App/Orders/OrderDetailView.swift#L87-L110 I had another question about using Live Activities from Xcode Preview. My question is from a different POV: I have a view component that performs some logic to start and end live activity. I am wondering… what kind of support do I have from Xcode Preview to then actually see that Live Activity in action as a kind of "end to end" test that my call to ActivityKit.Activity started an activity correctly? My understanding here is the supported way to test Live Activity starting and stopping is to actually run the app and start the activity from that component. There isn't a supported "shortcut" from Xcode Preview. Is that correct?
May ’25
Reply to Help understanding `SwiftUI.App` identity lifecycle and need for `SwiftUI.State`?
Hmm… I believe I do now have an understanding how a State variable would tie the lifecycle of its value to the lifecycle of a View component… but I am still unclear how this helps me to understand how a State variable defined on an App component can be expected to behave: https://developer.apple.com/documentation/swiftui/managing-user-interface-state This article has many examples of using State in a View component… but I do not see examples of using State in our App component. https://developer.apple.com/videos/play/wwdc2020/10040/?time=1852 This video does have an example of a StateObject being used as a global "source of truth" (which is going to be most similar to my use case)… but this video predates the release of State and Observable. https://developer.apple.com/videos/play/wwdc2023/10149 I believe this video has a close example from FoodTruckModel to achieve a similar feature to my use case. What this video seems to be missing is where this FoodTruckModel should first be created. Similar to the previous talk… this "global source of truth" looks like it should belong in my root App component… but then would that imply that FoodTruckModel be better initialized as a State var or as a regular Swift let? A side-question I would have here is how it would be possible for an engineer to stress-test their app in a way to cause the App component instance to be disposed by SwiftUI (and then rebuilt while the process is running). Is such a use case ever possible in an edge case? Is this something (recreating App component) that engineers should ever have to prepare for to defend against?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’24
Reply to SwiftUI.Stepper bug from `onIncrement` and `onDecrement`?
This is a more detailed example that shows some extra work from my production app: @main struct StepperDemoApp: App { var body: some Scene { WindowGroup { ContentView() } } } @Observable final class Number { var value: Int = 0 } struct ContentView: View { @State private var number = Number() func onIncrement() { number.value += 1 print(#function) } func onDecrement() { number.value -= 1 print(#function) } var body: some View { Stepper { Text("Stepper \(number.value)") } onIncrement: { self.onIncrement() } onDecrement: { self.onDecrement() } .padding() } } #Preview { ContentView() } In this example, the Stepper text label value depends on state (the number class), but I see the same unexpected behavior (potential bug) from my original example. My Stepper text label is correctly updating when the Observable value changes… but the onIncrement and onDecrement closures are in some kind of "bad" state. My original example showed how the Stepper behaves unexpectedly when no state is triggering a redraw. This new example behaves unexpectedly when state is triggering a redraw through an Observable object. Our previous example showed how Stepper behaves as expected when we trigger a redraw directly on state (without the indirection of an Observable object). All these repros are from macOS 14.6.1… deploying to iPhone simulator behaves as expected on all examples (no unexpected behavior).
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’24
Reply to SwiftUI.Stepper bug from `onIncrement` and `onDecrement`?
I've submitted a bug report myself and will see if I can find a workaround. Thanks! I am actually kind of "unblocked" in a different way by building my own custom component: @main struct StepperDemoApp: App { func onIncrement() { print(#function) } func onDecrement() { print(#function) } var body: some Scene { WindowGroup { VStack { Text("Stepper") Button("Increment") { self.onIncrement() } Button("Decrement") { self.onDecrement() } } .padding() } } } This unblocks my use case for my app… but I am still blocked from using the system Stepper component. If I did ship this custom component as a workaround it would be helpful for my repo to be able to explain to readers why this workaround is needed (because the production stepper component is potentially causing a bug on macOS).
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’24
Reply to SwiftUI.Stepper bug from `onIncrement` and `onDecrement`?
could you explain what you're using this for that's not updating any UI Thanks! The post here is an attempt at a MRE test case to show I am unable to see these two functions called how I expect on macOS (but iPhone simulator behaves as expected). My production app does more complex work in the onIncrement and onDecrement functions and I am not seeing that work being called correctly. I seem to be running into the same problem in my production app I have here in the MRE test case… without an explicit state or id refreshing the stepper then the macOS stepper seems to get in some weird situation where the + and - buttons do not dispatch correctly until the next manual refresh computes a new body.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’24
Reply to SwiftUI.Stepper bug from `onIncrement` and `onDecrement`?
I advise filing a bug report at https://feedbackassistant.apple.com and mentioning it. I actually haven't had very quick results from feedback assistant… the last bug I filed was Feb 12 and I still see no comments or any information from an Apple Engineer. This bug has been fixed but I did not see any comments or notifications for me to follow along with the progress in feedback assistant. I'm actually blocked on this Stepper. :( If I used one of my DTS service request support tickets would you be available to help investigate to confirm if this is a legit bug in the framework? My last DTS request was Oct 27 (last year) and I still have heard no response back from anyone at Apple. Could I file a DTS and ask for you to be the engineer if you have time? Thanks!
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’24
Reply to SwiftUI.Stepper bug from `onIncrement` and `onDecrement`?
Resetting the view id seems to lead to the correct values being printed on macOS: import SwiftUI @main struct StepperDemoApp: App { @State var id = UUID() func onIncrement() { print(#function) self.id = UUID() } func onDecrement() { print(#function) self.id = UUID() } var body: some Scene { WindowGroup { Stepper { Text("Stepper") } onIncrement: { self.onIncrement() } onDecrement: { self.onDecrement() } .id(self.id) } } } Tapping + + + - - -: onIncrement() onIncrement() onIncrement() onDecrement() onDecrement() onDecrement() This is a hack? Or a legit workaround for a known issue? Is some internal state in Stepper bad for some reason without this id hack? This one also works: var body: some Scene { WindowGroup { Stepper { Text(self.id.uuidString) } onIncrement: { self.onIncrement() } onDecrement: { self.onDecrement() } } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’24
Reply to Unhandled exception finding default Directory URL '+[NSPersistentContainer defaultDirectoryURL] Could not conjure up a useful location for writing persistent stores.'
import Benchmark import CoreData let benchmarks = { Benchmark("Benchmark") { benchmark in let _ = NSPersistentContainer.defaultDirectoryURL } } This crashes: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+[NSPersistentContainer defaultDirectoryURL] Could not conjure up a useful location for writing persistent stores.' *** First throw call stack: ( 0 CoreFoundation 0x0000000189caa2ec __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000018978e158 objc_exception_throw + 60 2 CoreData 0x00000001904d9034 __44+[NSPersistentContainer defaultDirectoryURL]_block_invoke + 0 3 CoreData 0x00000001905c3f74 $sSo21NSPersistentContainerC8CoreDataE19defaultDirectoryURL10Foundation0G0VvgZ + 40 4 Benchmarks 0x00000001047530e4 $s10Benchmarks10benchmarks9BenchmarkACCSgycvpfiAEycfU_yADcfU_ + 92 5 Benchmarks 0x0000000104703608 $s9Benchmark0A8ExecutorV3runySayAA0A6ResultVGA2ACF + 2640 6 Benchmarks 0x0000000104728f34 $s9Benchmark0A6RunnerV3runyyYaKFTY0_ + 6768 7 Benchmarks 0x0000000104725cb5 $s9Benchmark0A11RunnerHooksPAAE4mainyyYaFZTQ1_ + 1 8 Benchmarks 0x00000001047535a5 $sIetH_yts5Error_pIegHrzo_TR10async_MainTf3npf_nTQ0_ + 1 9 libswift_Concurrency.dylib 0x00000002513d6149 _ZL22completeTaskAndReleasePN5swift12AsyncContextEPNS_10SwiftErrorE + 1 ) libc++abi: terminating due to uncaught exception of type NSException
Aug ’24
Reply to Unhandled exception finding default Directory URL '+[NSPersistentContainer defaultDirectoryURL] Could not conjure up a useful location for writing persistent stores.'
CoreData: error: Failed to create directory file:///Users/rick/Library/Application%20Support/Benchmarks: NSCocoaErrorDomain (513) CoreData: fault: Unhandled exception finding default Directory URL '+[NSPersistentContainer defaultDirectoryURL] Could not conjure up a useful location for writing persistent stores.' https://github.com/vanvoorden/2024-08-26 I am running into these errors when attempting to run a benchmark on a SwiftData context from the 2024-08-26 repo. The errors seem to be harmless… the benchmark continues without crashing on those unhandled exceptions. https://github.com/vanvoorden/2024-08-02/ I seem to have no problem running against SwiftData from a different Swift Package Executable (2024-08-02). This package seems to build and run with no errors. This package also creates the expected directory under ~/Library/Application%20Support/2024-08-02. I don't yet completely understand what is happening… but there seems to be some reason why Benchmarks is failing to create that extra directory under Application%20Support. I can also run Benchmarks with no errors after I add the Application%20Support/Benchmarks directory manually from mac Finder. The benchmarks seem to be running correctly even after printing those errors… so I am not sure if there is anything important to fix in the Benchmarks package for now.
Aug ’24
Reply to SwiftData ModelContext fails to delete all model instances from unit tests.
The reference of delete(model:where:includeSubclasses:) doesn't mention that behavior, and I believe that is because delete(model:where:includeSubclasses:) goes down directly to the store to delete the objects (for better performance), like what NSBatchDeleteRequest does, and doesn't discard the unsaved objects in the context. Ahh… interesting! This is very valuable insight. Thanks! I am beginning to understand this behavior more. A follow up question is I am still looking for one "single shot" function to delete all model instances (including staged and pending models prior to save). I can think of (at least) three options: Explicitly save before attempting to delete all: func testSaveAndDelete() throws { let modelContext = ModelContext(container) modelContext.insert(Item()) print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 1) modelContext.insert(Item()) print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 2) try modelContext.save() try modelContext.delete(model: Item.self) print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 0) } Attempt to delete all and then follow up with an iteration through all remaining: func testSaveAndDeleteAndIterate() throws { let modelContext = ModelContext(container) modelContext.insert(Item()) print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 1) try modelContext.save() modelContext.insert(Item()) print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 2) try modelContext.delete(model: Item.self) print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 1) for model in try modelContext.fetch(FetchDescriptor<Item>()) { modelContext.delete(model) } print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 0) } Iterate through all inserted models prior to delete all: func testSaveAndIterateAndDelete() throws { let modelContext = ModelContext(container) modelContext.insert(Item()) print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 1) try modelContext.save() modelContext.insert(Item()) print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 2) for model in modelContext.insertedModelsArray { // TODO: filter only for `item` models! :D modelContext.delete(model) } print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 1) try modelContext.delete(model: Item.self) print(try modelContext.fetchCount(FetchDescriptor<Item>()) == 0) } All of these options seem to operate correctly and pass my tests. any opinion about which pattern might provide the right choice to optimize for memory and CPU? My intuition tells me the most efficient pattern might depend on the model schema and the state of this context at any point in time. Any more insight about what might be the right option here? Thanks!
Aug ’24