Private UIKit code causes a crash when the app moves to the background on iOS 26

After iOS 26 was released to the public and our build began rollout, we started seeing a strange crash affect users immediately after the app goes to the background. According to the symbolication provided in Xcode, this appears to be the result of a UICollectionView potentially related to the keyboard and a UIAlertController. I’m not sure how an error somewhere else can cause a crash in our app which does not use UIKit in the background.

The feedback associated with this post is: FB20305833. I will attach a sample of the crash report in my next comment.

Last Exception Backtrace:
0   CoreFoundation                	0x19a05e8c8 __exceptionPreprocess + 164 (NSException.m:249)
1   libobjc.A.dylib               	0x196fd57c4 objc_exception_throw + 88 (objc-exception.mm:356)
2   CoreFoundation                	0x19a070e88 -[__NSArrayM objectAtIndex:] + 592 (NSArrayM.m:142)
3   UIKitCore                     	0x1a0369758 -[_UIFlowLayoutInfo setSizes:forItemsAtIndexPaths:] + 316 (UIFlowLayoutSupport.m:2030)
4   UIKitCore                     	0x1a0355768 -[UICollectionViewFlowLayout _didPerformUpdateVisibleCellsPassWithLayoutOffset:] + 156 (UICollectionViewFlowLayout.m:2112)
5   UIKitCore                     	0x1a03136f0 -[UICollectionView _updateVisibleCellsNow:] + 3452 (UICollectionView.m:5683)
6   UIKitCore                     	0x19fa64604 -[UICollectionView layoutSubviews] + 280 (UICollectionView.m:6895)
7   UIKitCore                     	0x19f8aa078 UIView._layoutSubviewsWithObservationTracking() + 828 (_UIObservationTracking.swift:383)
8   UIKitCore                     	0x19f8aab38 @objc UIView._layoutSubviewsWithObservationTracking() + 36 (<compiler-generated>:0)
9   UIKitCore                     	0x1a1190f68 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2532 (UIView.m:20962)
10  QuartzCore                    	0x19aa009a8 CA::Layer::perform_update_(CA::Layer*, CALayer*, unsigned int, CA::Transaction*) + 352 (CALayer.mm:11185)
11  QuartzCore                    	0x19a9e32fc CA::Layer::update_if_needed(CA::Transaction*, unsigned int, unsigned int) + 600 (CALayer.mm:11262)
12  UIKitCore                     	0x19f8887b4 -[UIView(Hierarchy) layoutBelowIfNeeded] + 316 (UIView.m:15195)
13  UIKitCore                     	0x1a05c23e4 -[_UIAlertControllerPhoneTVMacView _updateTextAlignmentAfterLayout] + 124 (_UIAlertControllerPhoneTVMacView.m:3049)
14  UIKitCore                     	0x1a0095808 -[UIAlertController viewDidLayoutSubviews] + 156 (UIAlertController.m:928)
15  UIKitCore                     	0x19f8d4550 UIViewController._viewDidLayoutSubviewsWithObservationTracking() + 828 (_UIObservationTracking.swift:436)
16  UIKitCore                     	0x19f8d4938 @objc UIViewController._viewDidLayoutSubviewsWithObservationTracking() + 36 (<compiler-generated>:0)
17  UIKitCore                     	0x1a119120c -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 3208 (UIView.m:20993)
18  QuartzCore                    	0x19aa009a8 CA::Layer::perform_update_(CA::Layer*, CALayer*, unsigned int, CA::Transaction*) + 352 (CALayer.mm:11185)
19  QuartzCore                    	0x19a9e32fc CA::Layer::update_if_needed(CA::Transaction*, unsigned int, unsigned int) + 600 (CALayer.mm:11262)
20  UIKitCore                     	0x19f8887b4 -[UIView(Hierarchy) layoutBelowIfNeeded] + 316 (UIView.m:15195)
21  UIKitCore                     	0x1a06f6d2c __76-[_UIKeyboardLayoutAlignmentView _updateConstraintsForKeyboardNotification:]_block_invoke_3 + 60 (_UIKeyboardLayoutAlignmentView.m:181)
22  UIKitCore                     	0x1a1188b9c +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 516 (UIView.m:17651)
23  UIKitCore                     	0x1a11891f0 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 48 (UIView.m:17734)
24  UIKitCore                     	0x1a06f6cd0 __76-[_UIKeyboardLayoutAlignmentView _updateConstraintsForKeyboardNotification:]_block_invoke_2 + 160 (_UIKeyboardLayoutAlignmentView.m:179)
25  UIKitCore                     	0x1a06f6bd0 -[_UIKeyboardLayoutAlignmentView _updateConstraintsForKeyboardNotification:] + 772 (_UIKeyboardLayoutAlignmentView.m:190)
26  CoreFoundation                	0x199fe6a04 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 148 (CFNotificationCenter.c:702)
27  CoreFoundation                	0x199fe6ab4 ___CFXRegistrationPost_block_invoke + 92 (CFNotificationCenter.c:195)
28  CoreFoundation                	0x199fe6910 _CFXRegistrationPost + 436 (CFNotificationCenter.c:223)
29  CoreFoundation                	0x199fe70b0 _CFXNotificationPost + 736 (CFNotificationCenter.c:1249)
30  Foundation                    	0x197fb8c30 -[NSNotificationCenter postNotificationName:object:userInfo:] + 92 (NSNotification.m:598)
31  TextInputUI                   	0x1a6c71610 -[TUIKeyboardTrackingCoordinator postNotificationWithName:userInfo:] + 236 (TUIKeyboardTrackingCoordinator.m:1123)
32  TextInputUI                   	0x1a6c7115c -[TUIKeyboardTrackingCoordinator _postNotificationsWithAnimationInfo:type:start:] + 292 (TUIKeyboardTrackingCoordinator.m:0)
33  TextInputUI                   	0x1a6c71730 -[TUIKeyboardTrackingCoordinator postNotificationType:forStart:] + 140 (TUIKeyboardTrackingCoordinator.m:1113)
34  UIKitCore                     	0x1a0d3c134 __78-[UITrackingElementWindowController postValidatedStartNotifications:withInfo:]_block_invoke + 856 (UITrackingElementWindowController.m:1874)
35  UIKitCore                     	0x1a0d3bdb8 -[UITrackingElementWindowController postValidatedStartNotifications:withInfo:] + 228 (UITrackingElementWindowController.m:1905)
36  UIKitCore                     	0x1a0d3bcb0 -[UITrackingElementWindowController postStartNotifications:withInfo:] + 72 (UITrackingElementWindowController.m:1858)
37  UIKitCore                     	0x1a0d41528 __87-[UITrackingElementWindowController moveFromPlacement:toPlacement:starting:completion:]_block_invoke_4 + 1516 (UITrackingElementWindowController.m:2969)
38  UIKitCore                     	0x1a070646c -[UIInputViewAnimationStyle launchAnimation:afterStarted:completion:forHost:fromCurrentPosition:] + 396 (UIInputViewAnimationStyle.m:149)
39  UIKitCore                     	0x1a0d40b10 -[UITrackingElementWindowController moveFromPlacement:toPlacement:starting:completion:] + 3096 (UITrackingElementWindowController.m:3090)
40  UIKitCore                     	0x1a0d47e2c -[UITrackingElementWindowController setInputViewSet:] + 2412 (UITrackingElementWindowController.m:4203)
41  UIKitCore                     	0x1a0d3e390 -[UITrackingElementWindowController performOperations:withAnimationStyle:] + 68 (UITrackingElementWindowController.m:2440)
42  UIKitCore                     	0x1a0604b0c -[UIKeyboardSceneDelegate setKeyWindowSceneInputViews:animationStyle:] + 2780 (UIKeyboardSceneDelegate.m:2938)
43  UIKitCore                     	0x1a0603ff4 -[UIKeyboardSceneDelegate setInputViews:animationStyle:] + 188 (UIKeyboardSceneDelegate.m:2806)
44  UIKitCore                     	0x1a06050ac -[UIKeyboardSceneDelegate setInputViews:animated:] + 76 (UIKeyboardSceneDelegate.m:2994)
45  UIKitCore                     	0x1a0605110 -[UIKeyboardSceneDelegate setInputViews:] + 56 (UIKeyboardSceneDelegate.m:2999)
...

Continued from above

46  UIKitCore                     	0x1a0602558 __102-[UIKeyboardSceneDelegate _reloadInputViewsForKeyWindowSceneResponder:force:fromBecomeFirstResponder:]_block_invoke.587 + 36 (UIKeyboardSceneDelegate.m:2263)
47  UIKitCore                     	0x1a0a14fe8 __65-[UIPeripheralHost(UIKitInternal) queueDelayedTask:forKey:delay:]_block_invoke + 160 (UIPeripheralHost.m:975)
48  libdispatch.dylib             	0x1d19877ec _dispatch_client_callout + 16 (client_callout.mm:85)
49  libdispatch.dylib             	0x1d1972664 _dispatch_continuation_pop + 596 (queue.c:349)
50  libdispatch.dylib             	0x1d1985528 _dispatch_source_latch_and_call + 396 (source.c:601)
51  libdispatch.dylib             	0x1d19841fc _dispatch_source_invoke + 844 (source.c:966)
52  libdispatch.dylib             	0x1d19a4a48 _dispatch_main_queue_drain.cold.5 + 592 (queue.c:8181)
53  libdispatch.dylib             	0x1d197cec8 _dispatch_main_queue_drain + 180 (queue.c:8162)
54  libdispatch.dylib             	0x1d197ce04 _dispatch_main_queue_callback_4CF + 44 (queue.c:8341)
55  CoreFoundation                	0x19a000520 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1820)
56  CoreFoundation                	0x199fb2d14 __CFRunLoopRun + 1944 (CFRunLoop.c:3177)
57  CoreFoundation                	0x199fb1c44 _CFRunLoopRunSpecificWithOptions + 532 (CFRunLoop.c:3462)
58  GraphicsServices              	0x2393a6498 GSEventRunModal + 120 (GSEvent.c:2049)
59  UIKitCore                     	0x19f92cddc -[UIApplication _run] + 792 (UIApplication.m:3899)
60  UIKitCore                     	0x19f8d1b0c UIApplicationMain + 336 (UIApplication.m:5574)
61  Ohio State                    	0x1005a0144 main + 324 (main.swift:0)
62  dyld                          	0x19702ae28 start + 7116 (dyldMain.cpp:1477)

Thank you for your post. And thanks for the bug report. What version of Xcode and iOS are you using?

We have received your report FB20305833. We recommend that you provide a simple focus project that reproduces the issue.

Do you get the same results with just the relevant code in a small test project?

If so, please share a link to your test project. That'll help us better understand what's going on.

If you're not familiar with preparing a test project, take a look at Creating a test project.

Albert Pascual
  Worldwide Developer Relations.

CollectionView is a complex API, while I was developing my wrapper for SwiftUI I had similar bug. I don't have a tendency to jump right away on Apple and prefer investigate and see whether I am not doing something that's expected of me. (I work on AppKit app but this is applicable to UIKit as well) I inserted the code below into AppDelegate. This allowed me to catch the moment where NSArray.objectAtIndex returns nil, and after little research it turned out that my layout wasn't implementing some callback and wasn't returning attributes for the item at that index, because I didn't understand well enough the purpose of that callback (delegate method). After implementing that method it worked. I don't remember specific details but this is the code you can modify to swizzle NSArray.objectAtIndex, it has to be done in applicationWillFinishLaunching.

// MARK: - swizzling -[NSMutableArray insertObject:atIndex:]
#if false
func swizzle_NSMutableArray() {
	let oldClass: AnyClass! = NSClassFromString("__NSArrayM")
	guard let oldMethod = class_getInstanceMethod(oldClass, NSMutableArray.oldSelector),
		let newMethod = class_getInstanceMethod(oldClass, #selector(NSMutableArray.new_insert(_:at:))) else {
		print("unable to swizzle -[NSMutableArray insertObject:atIndex:] method")
		return
	}
	NSMutableArray.oldIMP = method_setImplementation(oldMethod, method_getImplementation(newMethod))
}

extension NSMutableArray {
	fileprivate static let oldSelector = NSSelectorFromString("insertObject:atIndex:")
	fileprivate static var oldIMP: IMP!
	fileprivate static var oldInsertObjectAtIndex: ((NSMutableArray, Any, Int) -> Void)?
	@objc
	dynamic nonisolated func new_insert(_ object: Any?, at index: Int) {
		let old = unsafeBitCast(NSMutableArray.oldIMP, to: (@convention(c) (Any?, Selector?, Any?, Int) -> Void).self)
		if object == nil {
			print(index)
			print(self)
		}
		return old(self, NSMutableArray.oldSelector, object, index)
	}
}
#endif
Private UIKit code causes a crash when the app moves to the background on iOS 26
 
 
Q