Please simulate the following app on Xcode's simulator:
import UIKit
import CoreLocationUI
class ViewController: UIViewController {
let textField: UITextField = {
let tf = UITextField()
tf.backgroundColor = .systemGray6
tf.placeholder = "Tap me"
tf.leftView = UIView(frame: .init(x: 0, y: 0, width: 8, height: 0))
tf.leftViewMode = .always
tf.layer.cornerRadius = 11
return tf
}()
let locationButton = CLLocationButton()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
view.addSubview(textField)
view.addSubview(locationButton)
textField.translatesAutoresizingMaskIntoConstraints = false
locationButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
textField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
textField.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8),
textField.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.85),
textField.heightAnchor.constraint(equalToConstant: 44),
locationButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
locationButton.topAnchor.constraint(equalTo: textField.bottomAnchor, constant: 8),
locationButton.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.85),
locationButton.heightAnchor.constraint(equalToConstant: 44),
])
}
}
If I tap on the text field, the app crashes. Error message:
Thread 1: "*** -[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: arrow.uturn.forward)".
Xcode 15.3, MacBook Air M1 8GB, macOS Sonoma 14.4, simulator os: iOS 17.4.
I've noticed that it doesn't crash on my iPhone SE 1st gen (iOS 15.8).
I don't have other iOS devices to try it on unfortunately.
Is this just a simulator bug?
Console log:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSDictionaryM setObject:forKey:]: object cannot be nil (key: arrow.uturn.forward)'
*** First throw call stack:
(
0 CoreFoundation 0x00000001804ae138 __exceptionPreprocess + 172
1 libobjc.A.dylib 0x0000000180087db4 objc_exception_throw + 56
2 CoreFoundation 0x000000018051e88c -[__NSDictionaryM setObject:forKey:] + 1232
3 UIKitCore 0x00000001856c0f44 +[UIAssistantBarButtonItemProvider configuredSymbolImageWithName:size:] + 344
4 UIKitCore 0x00000001856c00bc +[UIAssistantBarButtonItemProvider barButtonItemForAssistantItemStyle:target:forcePlainButton:] + 2120
5 UIKitCore 0x00000001856c1200 +[UIAssistantBarButtonItemProvider defaultSystemLeadingBarButtonGroupsForItem:] + 204
6 UIKitCore 0x00000001856c1754 +[UIAssistantBarButtonItemProvider systemDefaultAssistantItem] + 48
7 UIKitCore 0x0000000185417e0c -[UIResponder(UIResponderInputViewAdditions) inputAssistantItem] + 64
8 UIKitCore 0x0000000185717710 -[UITextField inputAssistantItem] + 64
9 UIKitCore 0x0000000185417d4c _UIResponderFindInputAssistantItem + 44
10 UIKitCore 0x0000000184d79c18 -[UISystemInputAssistantViewController isVisibleWhenMinimized] + 96
11 UIKitCore 0x000000018523c12c +[UIPeripheralHost(UIKitInternal) endPlacementForInputViewSet:windowScene:] + 1292
12 UIKitCore 0x0000000184e0b2d0 -[UIKeyboardSceneDelegate prepareToMoveKeyboardForInputViewSet:animationStyle:] + 192
13 UIKitCore 0x0000000184e0a060 -[UIKeyboardSceneDelegate setKeyWindowSceneInputViews:animationStyle:] + 1396
14 UIKitCore 0x0000000184e09ab8 -[UIKeyboardSceneDelegate setInputViews:animationStyle:] + 132
15 UIKitCore 0x0000000184e0aaa4 -[UIKeyboardSceneDelegate setInputViews:animated:] + 72
16 UIKitCore 0x0000000184e0aaf4 -[UIKeyboardSceneDelegate setInputViews:] + 52
17 UIKitCore 0x0000000184e081f0 __102-[UIKeyboardSceneDelegate _reloadInputViewsForKeyWindowSceneResponder:force:fromBecomeFirstResponder:]_block_invoke.484 + 24
18 UIKitCore 0x00000001852386e0 __65-[UIPeripheralHost(UIKitInternal) queueDelayedTask:forKey:delay:]_block_invoke + 156
19 libdispatch.dylib 0x00000001016fd73c _dispatch_client_callout + 16
20 libdispatch.dylib 0x0000000101700c14 _dispatch_continuation_pop + 756
21 libdispatch.dylib 0x00000001017164e0 _dispatch_source_invoke + 1736
22 libdispatch.dylib 0x000000010170d2a8 _dispatch_main_queue_drain + 892
23 libdispatch.dylib 0x000000010170cf1c _dispatch_main_queue_callback_4CF + 40
24 CoreFoundation 0x000000018040e9a0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
25 CoreFoundation 0x00000001804090b8 __CFRunLoopRun + 1936
26 CoreFoundation 0x0000000180408514 CFRunLoopRunSpecific + 572
27 GraphicsServices 0x000000018ef06ae4 GSEventRunModal + 160
28 UIKitCore 0x00000001853e8040 -[UIApplication _run] + 868
29 UIKitCore 0x00000001853ebcc8 UIApplicationMain + 124
30 UIKitCore 0x000000018488c1cc __swift_destroy_boxed_opaque_existential_1Tm + 10048
31 Crash_CLLocationButton 0x000000010057044c $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 120
32 Crash_CLLocationButton 0x00000001005703c4 $s22Crash_CLLocationButton11AppDelegateC5$mainyyFZ + 44
33 Crash_CLLocationButton 0x00000001005704c8 main + 28
34 dyld 0x00000001005d1544 start_sim + 20
35 ??? 0x00000001006e60e0 0x0 + 4302201056
36 ??? 0x027c800000000000 0x0 + 179158822676332544
)
libc++abi: terminating due to uncaught exception of type NSException
This is definitely an iOS bug that appears when the app is run on an iPad or iPad simulator with iOS 17. The crash does not happen with iOS 15 or 16 (at least with iOS 15.5 or 16.4).
The error mentions a value of arrow.uturn.forward
. This is an SF Symbol name typically used for the "Redo" button shown in the toolbar of an iPad keyboard.
If the app creates an instance of CLLocationButton
(regardless of whether the button is added to the view hierarchy or not), the bug appears. Under iOS 17 the app crashes as shown in the question. Under iOS 15 and 16, the crash does not happen but the normal undo/redo/paste icons are replaced by the words "Undo"/"Redo"/Paste". Oddly, under iOS 16, the paste button shows both the word "Paste" and the paste icon overlaid on each other.
There is a work around. Add the following two lines to the UITextField
setup code:
tf.inputAssistantItem.leadingBarButtonGroups = []
tf.inputAssistantItem.trailingBarButtonGroups = []
Those two lines remove the buttons from the iPad keyboard toolbar which in turn prevents the crash. It may not be ideal to remove those toolbar items but it is better than the app crashing.
Meanwhile, use the Feedback Assistant app and submit a complete test app using your code as a demonstration for this bug. Feel free to include info from this answer as well.