Description
I've encountered a consistent hang/freeze issue in SwiftUI applications when using nested LazyVStack containers with Accessibility Inspector (simulator) or VoiceOver (physical device) enabled. The application becomes completely unresponsive and must be force-quit.
Importantly, this hang occurs in a minimal SwiftUI project with no third-party dependencies, suggesting this is a framework-level issue with the interaction between SwiftUI's lazy view lifecycle and the accessibility system.
Reproduction Steps
I've created a minimal reproduction project available here:
https://github.com/pendo-io/SwiftUI_Hang_Reproduction
To Reproduce:
Create a SwiftUI view with the following nested LazyVStack structure:
struct NestedLazyVStackView: View {
@State private var outerSections: [Int] = []
@State private var innerRows: [Int: [Int]] = [:]
var body: some View {
ScrollView {
LazyVStack(alignment: .leading, spacing: 24) {
ForEach(outerSections, id: \.self) { section in
VStack(alignment: .leading, spacing: 8) {
Text("Section #\(section)")
// Nested LazyVStack
LazyVStack(alignment: .leading, spacing: 2) {
ForEach(innerRows[section] ?? [], id: \.self) { row in
Text("Section #\(section) - Row #\(row)")
.onAppear {
// Load more data when row appears
loadMoreInner(section: section)
}
}
}
}
.onAppear {
// Load more sections when section appears
loadMoreOuter()
}
}
}
}
}
}
Enable Accessibility Inspector in iOS Simulator:
Xcode → Open Developer Tool → Accessibility Inspector
Select your running simulator
Enable Inspection mode (eye icon)
Navigate to the view and start scrolling
Result: The application hangs and becomes unresponsive within a few seconds of scrolling
Expected Behavior
The application should remain responsive when Accessibility Inspector or VoiceOver is enabled, allowing users to scroll through nested lazy containers without freezing.
Actual Behavior
The application freezes/hangs completely
CPU usage may spike
The app must be force-quit to recover
The hang occurs consistently and is reproducible
Workaround 1: Replace inner LazyVStack with VStack
LazyVStack {
ForEach(...) { section in
VStack { // ← Changed from LazyVStack
ForEach(...) { row in
...
}
}
}
}
Workaround 2: Embed in TabView
TabView {
NavigationStack {
NestedLazyVStackView() // ← Same nested structure, but no hang
}
.tabItem { ... }
}
Interestingly, wrapping the entire navigation stack in a TabView prevents the hang entirely, even with the nested LazyVStack structure intact.
Questions for Apple
Is there a known issue with nested LazyVStack containers and accessibility traversal?
Why does wrapping the view in a TabView prevent the hang?
Are there recommended patterns for using nested lazy containers with accessibility support?
Is this a timing issue, a deadlock, or an infinite loop in the accessibility system?
Why that happens?
Reproduction Project
A complete, minimal reproduction project is available at:
https://github.com/pendo-io/SwiftUI_Hang_Reproduction
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am seeing a strange issue where NSObject accessibilityRespondsToUserInteraction returns true on Simulator but false on device.
Checking the same object on simulator with Accessibility inspector I see the object traits as image so why would it return true in that case?
Are there any other way to check the the item might be accessibilityRespondsToUserInteraction OR Clickable beside that property and traits?
(Or is it just another bug)
I am trying to run Xcode 15 on macOS 15.4.
As we need to build framework with older versions of Xcode.
Any work around for it?
for instance:
po [NSBundle mainBundle]
0x0000600002130000
p [NSBundle mainBundle]
(NSBundle *) 0x0000600002130000
p [[NSBundle mainBundle] bundlePath]
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x0).
The process has been returned to the state before expression evaluation.
I am in debug mode
So I will summary an issue one of our clients has asked us on GitHub:
https://github.com/pendo-io/pendo-mobile-sdk/issues/233
Project that is a custom framework that uses different SPM packages (one of them is Binary package), we have our main logic inside that framework and we have different targets that use this framework, everything works on the simulator, but running the app on the actual device provokes a crash saying "Binary framework was not found". We have like 20 other SPM packages that work fine, this is the first one we have an issue with.
Please note I understand that SPM will not copy paste the Binary for the magic framework as it does for the apps so I suggested to embed it manually.
So my question is what the best(easy) way to do it.
Please refer to the following issue for more details:
https://github.com/pendo-io/pendo-mobile-sdk/issues/233
Hello,
We're developing an SDK for iOS and need clarification on Apple's policies regarding the use of JavaScriptCore.
Specifically, we want to understand if it's permissible to execute JavaScript code provided by our customers using JavaScriptCore.
Our use case is as follows: Our customers will supply JavaScript code snippets, which our SDK will receive as text. The intention is to run these code snippets via JavaScriptCore to present interactive guides or dynamic content to the end-users of the app.
Would executing customer-provided JavaScript code in this manner be considered a violation of Apple's App Store guidelines?
I would like a shortcut for deleting view in swiftui
VStack {
// long code
}
How to delete VStack with its ending curly bracket?
Thanks
I am on M1 (Xcode Version 15.4 (15F31d), MacOS 14.5 (23F79), Simulator IOS 17.4) and as far as I remember printing common usage register was possible. I am not sure why it stopped to work rid, rsi and etc
(arg1 arg2 seems like still working).
if we define a property in the following way:
@property (atomic) NSString *latestObject;
Can we assume that the read write to that value is thread safe?
i.e the value will be correct.
Or it is better to write our own setter/getter with Locks?
Attaching several crash traces:
2024-02-29_22-48-33.6864_-0600-3f948243e21b4c68d77a38d9cf1cecfdfe2c1565.crash
2024-03-04_15-00-02.9335_-0600-75000cd5acd63ba1434f2ffb3648b97259dddb88.crash
2024-03-05_08-55-47.2097_-0500-f682b25663107ad46f091d65f402f2be31f3f3c6.crash
2024-03-11_08-09-00.4057_-0400-e37d1a635d51afbb67ac38b42dd79c1718a408e8.crash
2024-03-15_16-20-22.6446_-0600-d4ebccf455e8305038ca564a39a5661a1dce6231.crash
The final code:
- (NSObject*)objectAtIndex:(NSUInteger)index {
if (index < self.count) {
return [self.embeddedArray objectAtIndex:index];
} else {
[PNDErrorReporting reportError:PNDErrorReasonTypeSafeCollectionCrashPrevented message:@"Error msg"];
return nil;
}
}
We subclass NSMutableArray to prevent potential crashes. but we encounter a new crash in our sdk for one of the clients.
Also we noticed the stack trace skipped one of the frames (stack calls) in the crash report, in which cases the stack trace wont be identical to the actual code (beside inline)?
It seems that that all the crashes are coming from the same place BUT the error is slightly different.
Attaching the code that responsible for the crash:
static NSString * const kDelimiter = @"#$@";
+ (PNDArray *)getObjectsFromData:(NSData *)data {
NSString *dataStr = [[NSString alloc] initWithData:data encoding:encoding];
dataStr = [dataStr stringByReplacingOccurrencesOfString:@"\\u0000" withString:@""];
NSArray *components = [dataStr componentsSeparatedByString:kDelimiter];
NSMutableArray *result = [NSMutableArray array];
for (NSString *jsonStr in components) {
if (jsonStr != nil && jsonStr.length != 0 && ![jsonStr hasPrefix:kBatchUUID]) {
[result addObject:jsonStr];
}
}
return [PNDArray arrayWithArray:result];
}
2024-04-16_17-15-34.1922_-0600-dfa2faecf702f23e3f6558bea986de4f62851761.crash
2024-04-24_04-56-53.4664_-0500-6b125d3d03b7e497b6be339c2abb52f29658824b.crash
2024-04-25_11-13-53.1326_-0700-bfe370be3eae8d65f465eac714905dd3d13aa665.crash
2024-05-03_11-47-36.6085_-0500-2793587e7ed1c02b0e4334bbc3aa0bd7f7a0cf3d.crash
2024-05-05_10-49-40.5969_-0700-4d86636b0877fceb8c0cdb9586ee16dfb0a9c934.crash
In our third party SDK we would like to use microphone (as optional feature) in case the hosting app allows it.
From the docs requestRecordPermission will crash if no NSMicrophoneUsageDescription exists in the hosting app info.plist.
Obviously I don't want to crash the app. I would like to check if the hosting app will allow me to call requestRecordPermission before calling it?
Is it possible
I have a general question that confusing me.
I am on M1 and I can build my app on Xcode (or create an archive) for device. Looking in to derived data I can see Debug-iphones (and simulators) folders, I can get the .app and drag/drop it to the simulator. When trying to run the app the app will crash with error:
EXEC 14 Binary with wrong platform
I understand that it wasn't build for simulators but rather it was build for devices and there fore the crash, but when thinking about it I dont understand why? (at least theoretically it shouldn't crash as it was build for arm64 ). Inspected the binary with lipo it was build for arm64. Comparing the binaries for simulator and device (with otool) I dont see a lot of difference except the rpath.
So how does IOS knows it was build for device and not simulator (wrong platform)?
is there a way to add some sort of relaxation (in the end both binaries were build for arm64).
I have the following crash in swiftui that relates to memory reallocation, which I am not sure how to handle
Crash.txt
One of our client has contacted us with the following error :
Task .&lt;3&gt; request https:URL is NOT allowed to set HSTS for main doc (null)
Th request is sent from our SDK. According to the client it happens only on Vision Pro.
All our requests to the server on the SDK side are https.
The serve has the following header: X-Content-Type-Options X-Frame-Options Strict-Transport-Security
Can somebody share some insight?