I'm seeing an unexplained crash on my iOS app built with SwiftUI. It only affects some users, and I can't manage to reproduce locally.
Here is the stack trace:
Fatal Exception: NSInvalidArgumentException
<_TtGC7SwiftUI41StyleContextSplitViewNavigationControllerVS_19SidebarStyleContext_: 0x110859800>
is pushing the same view controller instance(<_TtGC7SwiftUI41StyleContextSplitViewNavigationControllerVS_14NoStyleContext_: 0x11088a400>)
more than once which is not supported and is most likely an error in the application : `com.myapp`
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x1893a186c __exceptionPreprocess
1 libobjc.A.dylib 0x19e3bcc50 objc_exception_throw
2 UIKitCore 0x18b575514 -[UINavigationController pushViewController:transition:forceImmediate:]
3 UIKitCore 0x18b5751f4 -[UINavigationController pushViewController:animated:]
4 UIKitCore 0x18b6047c8 __45-[UISplitViewControllerPanelImpl showColumn:]_block_invoke
5 UIKitCore 0x18b57eda8 -[UINavigationController _executeSplitViewControllerActions:]
6 UIKitCore 0x18b6045bc -[UISplitViewControllerPanelImpl showColumn:]
7 UIKitCore 0x18b5e4c54 -[UISplitViewController showColumn:]
8 SwiftUI 0x1903784f4 closure #1 in closure #1 in NavigationBridge_PhoneTV.push(_:onto:animated:)
9 SwiftUI 0x19042728c thunk for #escaping #callee_guaranteed () -> ()
10 UIKitCore 0x18c23f544 -[_UIAfterCACommitBlock run]
11 UIKitCore 0x18bd6700c _runAfterCACommitDeferredBlocks
12 UIKitCore 0x18bd559a0 _cleanUpAfterCAFlushAndRunDeferredBlocks
13 UIKitCore 0x18bd89bb4 _afterCACommitHandler
14 CoreFoundation 0x18931c358 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
15 CoreFoundation 0x1893165c4 __CFRunLoopDoObservers
16 CoreFoundation 0x189316b74 __CFRunLoopRun
17 CoreFoundation 0x18931621c CFRunLoopRunSpecific
18 GraphicsServices 0x1a0ee2784 GSEventRunModal
19 UIKitCore 0x18bd56ee8 -[UIApplication _run]
20 UIKitCore 0x18bd5c75c UIApplicationMain
21 MYAPP 0x100dbecc0 main + 7 (PushupsMode.swift:7)
22 libdyld.dylib 0x188fd66b0 start
Looking at PushupsMode.swift:7 it seems completely unrelated:
import Foundation
extension WorkoutModel {
mutating func startPushups() {
var pushupsCount = 10 + p.intensityOptionPicked * 10
if(round > 6 || round < 3) { // <<--- this is the line crashing
pushupsCount = Int(pushupsCount / 2)
}
// More code after that point
}
}
The round variable is defined in another file, but there's nothing really significant around it:
import Foundation
import SwiftUI
struct WorkoutModel: Identifiable {
// bunch of stuff before
var round: Int = -1
// bunch of stuff after
}
Obviously looking at the error message, it seems like something is getting pushed twice... however since I'm using SwiftUI I'm not entirely sure how I could have even done that.
Any pointers would be appreciated!
Your problem may be that you are defining pushupsCount as an Int( on PushupsMode.swift:8 which is causing the exception on :7 from :8 failing pre-execution. Try defining it as pushupsCount = Int pushupsCount / 2 .
Using pushViewController:transition:forceImmediate is not a good idea because pushViewController:animated will be calling on this undocumented method. Rather than changing transition this way you can use other documented methods for changing animation. This thread might be helpful for you. You will also need to add guard in pushViewController:animated and will also need to set transition.duration. Calling pushViewController again and again is perhaps causing crash of app.
This problem is caused when you place your navigationLink inside of a List with observed data.
How to fix :
Remove NavigationLink from inside of the list and place it outside.
Related
Recently a crash popped up in Firebase Crashlytics and I have no clue what it means. The message says:
Fatal Exception: NSInternalInconsistencyException
Trying to complete an interactive gesture but the animation coordinator is nil! (gesture=<_UIBarPanGestureRecognizer: 0x109f177c0; state = Ended; view = <UILayoutContainerView 0x1059153a0>; target= <(action=_gestureRecognizedInteractiveHide:, target=<UINavigationController 0x106837800>)>> action=Show)
and the stack trace looks like this:
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x9904c __exceptionPreprocess
1 libobjc.A.dylib 0x15f54 objc_exception_throw
2 Foundation 0x1306cc _userInfoForFileAndLine
3 UIKitCore 0x918cec -[UINavigationController _gestureRecognizedInteractiveHide:]
4 UIKitCore 0x1e042c -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:]
5 UIKitCore 0x1a9560 _UIGestureRecognizerSendTargetActions
6 UIKitCore 0x172260 _UIGestureRecognizerSendActions
7 UIKitCore 0x1ab910 -[UIGestureRecognizer _updateGestureForActiveEvents]
8 UIKitCore 0x163ad0 _UIGestureEnvironmentUpdate
9 UIKitCore 0x1978c8 -[UIGestureEnvironment _updateForEvent:window:]
10 UIKitCore 0x1a4a68 -[UIWindow sendEvent:]
11 UIKitCore 0x354318 -[UIApplication sendEvent:]
12 UIKitCore 0x177c30 __dispatchPreprocessedEventFromEventQueue
13 UIKitCore 0x16ca1c __processEventQueue
14 UIKitCore 0xfae7dc updateCycleEntry
15 UIKitCore 0x7dd7d8 _UIUpdateSequenceRun
16 UIKitCore 0xe57008 schedulerStepScheduledMainSection
17 UIKitCore 0xe565f8 runloopSourceCallback
18 CoreFoundation 0xbb020 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
19 CoreFoundation 0xcbce0 __CFRunLoopDoSource0
20 CoreFoundation 0x5fe8 __CFRunLoopDoSources0
21 CoreFoundation 0xb7f4 __CFRunLoopRun
22 CoreFoundation 0x1f3b8 CFRunLoopRunSpecific
23 GraphicsServices 0x138c GSEventRunModal
24 UIKitCore 0x5196a8 -[UIApplication _run]
25 UIKitCore 0x2987f4 UIApplicationMain
26 libswiftUIKit.dylib 0x31184 UIApplicationMain(_:_:_:_:)
27 MYAPPNAME 0x7220 main (MyAppStruct.swift)
28 ??? 0x104bb9a24 (Missing)
The MyAppStruct.swift is the only file in the trace that comes from my source code. It is just a struct which holds data and has some static methods for calculations. There is absolutely no relation with gestures and animations in this struct.
This only happened on iOS 15.1.1 devices (iPhone 12 and iPhone 13 Pro) for now.
I've managed to constantly reproduce this on an iPad 10.2 (9th gen). In my view controller, I have a scroll view as the top-most view in the hierarchy, and I was hiding/showing the navigation bar using the navigationController?.hidesBarsOnSwipe property. This property was set to true only when the scrollView's contentSize.height was greater than the view.bounds.height. The idea is to hide the navigation bar if the content scrolls, otherwise leave it visible and ignore the swipe gesture.
The issue only occurred when the scrollView's contentSize.height was just about 50pt larger than the view.height, which happens really, really rarely.
I removed the navigationController?.hidesBarsOnSwipe and used the scrollViewDidScroll method instead:
extension HomeViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y <= 10 {
// scroll up
navigationController?.setNavigationBarHidden(false, animated: true)
} else if scrollView.contentOffset.y >= 10 {
// scroll down
navigationController?.setNavigationBarHidden(true, animated: true)
}
}
}
FYI, I have a bug scenario that shows a similarly weird traceback (GUI event dispatched from inside UIKit's update cycle!?), and I have posted a report to Apple Developer Forums here:
https://developer.apple.com/forums/thread/699670
I don't think this is the "normal" way for GUI events to be dispatched. Seems hardly surprising that things could go wrong in the event handler.
I am facing this crash in my iOS app.
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x1b9079c30 __exceptionPreprocess
1 libobjc.A.dylib 0x1b8d940c8 objc_exception_throw
2 CoreFoundation 0x1b8f77fc0 -[NSOrderedSet initWithSet:copyItems:]
3 CoreFoundation 0x1b907e3d4 ___forwarding___
4 CoreFoundation 0x1b9080570 _CF_forwarding_prep_0
5 UIKitCore 0x1bcf33444 -[UIKeyboardImpl deleteForwardAndNotify:]
6 UIKitCore 0x1bcf39154 __57-[UIKeyboardImpl acceptPredictiveInput:executionContext:]_block_invoke
7 UIKitCore 0x1bcf5b0c8 -[UIKeyboardTaskExecutionContext returnExecutionToParentWithInfo:]
8 UIKitCore 0x1bcf366ec __100-[UIKeyboardImpl addWordTerminator:afterSpace:afterAcceptingCandidate:elapsedTime:executionContext:]_block_invoke
9 UIKitCore 0x1bcf5b0c8 -[UIKeyboardTaskExecutionContext returnExecutionToParentWithInfo:]
10 UIKitCore 0x1bcf2bdc0 __55-[UIKeyboardImpl handleKeyboardInput:executionContext:]_block_invoke_2
11 UIKitCore 0x1bcf5cd70 -[UIKeyboardTaskEntry execute:]
12 UIKitCore 0x1bcf5b6d4 -[UIKeyboardTaskQueue continueExecutionOnMainThread]
13 libobjc.A.dylib 0x1b8d8faf0 -[NSObject performSelector:withObject:]
14 Foundation 0x1b946ec10 __NSThreadPerformPerform
15 CoreFoundation 0x1b8ff5260 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
16 CoreFoundation 0x1b8ff51b4 __CFRunLoopDoSource0
17 CoreFoundation 0x1b8ff4920 __CFRunLoopDoSources0
18 CoreFoundation 0x1b8fef7ec __CFRunLoopRun
19 CoreFoundation 0x1b8fef098 CFRunLoopRunSpecific
20 GraphicsServices 0x1c3159534 GSEventRunModal
21 UIKitCore 0x1bd10f7ac UIApplicationMain
22 Haraj 0x102fc6058 main + 15 (main.m:15)
23 libdyld.dylib 0x1b8e6ef30 <redacted>
So far over a 100 crashes has been reported. This is happening only in iOS 12 and iOS 13.
I am not able to find how this is happening and how to reproduce it.
The stack trace does not show any of my app's code.
I have uploaded the full crash report here.
Any help would be highly appreciated.
This seems to be a regression of an ancient bug related to "forward delete" on iOS text entry: http://www.openradar.me/15114422
I believe it has regressed because of the new "swipe to type" keyboard.
You have 2 options to fix:
Upgrade your deprecated UIWebView to a WKWebView
Hacky solution: insert the missing selector on UIThreadSafeNode at runtime.
Here's a code example of how to insert the missing selector:
BOOL canPerformAction(id withSender) {
return false;
}
- (void)viewDidLoad {
[super viewDidLoad];
Class class = NSClassFromString(#"UIThreadSafeNode");
class_addMethod(class, #selector(canPerformAction:withSender:), (IMP)canPerformAction, "##:");
}
You should probably put the method insertion somewhere that only loads once, like in the AppDelegate.
Here's the full example project if you need it:
https://github.com/elliotfiske/UIWebView-TextEntry-CrashFix/tree/master
How to reproduce:
Create a text entry form in a UIWebView, type some words, then move the cursor to the exact END of a word in the middle of the sentence.
Then, choose any of the predictive text suggestions. See the bug in action here:
My app is in production and I've been getting a few crashes on Crashlytics when trying to cast the first element of a festRequest to a certain entity. I've not been able to recreate this crash no matter how hard I try.
static func getSettings() -> NotificationSettingsMO {
var settings: NotificationSettingsMO!
let moc = DataController.shared.managedObjectContext
moc.performAndWait {
do {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "NotificationSettings")
settings = try moc.fetch(fetchRequest).first as! NotificationSettingsMO
} catch {
print(error)
}
}
return settings
The crash happens when trying to cast the first element of the request to NotificationSettingsMO and I'm sure the entity exists since I create it when the user is created. This also only happens to a small percentage of users, but since it crashes the app I want to try and figure out what is causing it.
EDIT: I've attached the crash log
Crashed: com.apple.main-thread
0 MyApp 0x100073360 specialized static NotificationSettingsMO.(getSettings() -> NotificationSettingsMO).(closure #1) (NotificationSettingsMO.swift:25)
1 MyApp 0x10007309c partial apply for static NotificationSettingsMO.(getSettings() -> NotificationSettingsMO).(closure #1) (NotificationSettingsMO.swift)
2 CoreData 0x18311d08c developerSubmittedBlockToNSManagedObjectContextPerform + 196
3 CoreData 0x18311cf54 -[NSManagedObjectContext performBlockAndWait:] + 220
4 MyApp 0x100072fa8 specialized static NotificationSettingsMO.getSettings() -> NotificationSettingsMO (NotificationSettingsMO.swift)
5 MyApp 0x1000d6190 AppDelegate.getDataOnLaunch() -> () (AppDelegate.swift)
6 MyApp 0x1000da4bc specialized AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool (AppDelegate.swift:99)
7 MyApp 0x1000d3eb8 #objc AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool (AppDelegate.swift)
8 UIKit 0x1863f29c0 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 400
9 UIKit 0x186622184 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2904
10 UIKit 0x1866265f0 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1684
11 UIKit 0x186623764 -[UIApplication workspaceDidEndTransaction:] + 168
12 FrontBoardServices 0x182bbf7ac __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 36
13 FrontBoardServices 0x182bbf618 -[FBSSerialQueue _performNext] + 168
14 FrontBoardServices 0x182bbf9c8 -[FBSSerialQueue _performNextFromRunLoopSource] + 56
15 CoreFoundation 0x1811d509c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
16 CoreFoundation 0x1811d4b30 __CFRunLoopDoSources0 + 540
17 CoreFoundation 0x1811d2830 __CFRunLoopRun + 724
18 CoreFoundation 0x1810fcc50 CFRunLoopRunSpecific + 384
19 UIKit 0x1863eb94c -[UIApplication _run] + 460
20 UIKit 0x1863e6088 UIApplicationMain + 204
21 MyApp 0x10001ee18 main (Measurement+Network.swift:26)
22 libdispatch.dylib 0x180c9a8b8 (Missing)
The object does not exists so it crashes. Personally I HATE force casting in swift. The whole point of optionals is to help you manage when something is nil. Putting as! in your code is asking the program to crash. I would suggest removing it and replacing it with an if let. If you are 100% sure that it will never be nil then you should still use an if let and in the else report to crash service that it happened (use Crashlytics recordError - it will show up along with your crashes).
As for your statement:
I'm sure the entity exists since I create it when the user is created
to put it bluntly - you are wrong. Computers are always right and humans are always wrong.
Here are the possible reasons why:
There was an error saving it to core data I suspect that like most programs when you saved the object to core data you did not check for errors - or if you did you didn't really know what to do with the error. If you were smart you would have logged it. The most common error to get is lack of space on the hard disk. If the object wasn't saved in the first place then it wouldn't be there when you fetch it.
The object was there but was deleted. If you have anywhere in your code that deletes this object, then consider the possibility that it was deleted before this code ran. Look for multithreading and race conditions.
The object wasn't save yet. If you have ANY multithreading in the app you should consider the possibility that there is a race condition.
Any of these situations would cause crashes in the 0-3% range.
Can't reproduce following crash.
I already handled the case : not segueing the viewcontroller while one viewcontroller is animating. Similar problem mentioned here: iOS app error - Can't add self as subview. I have implemented this solution for safe segueing.
Still I am getting following crash.
Note: getting crash on both iOS 7 and 8 but more crash occurrence for iOS 8.(if that helps). Not getting crash in simulator even if segueing from viewDidLoad.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't add self as subview'
Application Specific Backtrace 1:
0 CoreFoundation 0x24503f87 <redacted> + 126
1 libobjc.A.dylib 0x31c62c77 _objc_exception_throw + 38
2 CoreFoundation 0x24503ecd -[NSException initWithCoder:] + 0
3 UIKit 0x279880b3 -[UIView _addSubview:positioned:relativeTo:] + 114
4 UIKit 0x27988037 -[UIView addSubview:] + 30
5 UIKit 0x27b4d491 <redacted> + 1236
6 UIKit 0x2798e701 +[UIView performWithoutAnimation:] + 72
7 UIKit 0x27b4cd79 -[_UINavigationParallaxTransition animateTransition:] + 808
8 UIKit 0x27b0b787 -[UINavigationController _startCustomTransition:] + 2854
9 UIKit 0x27a2ab2f -[UINavigationController _startDeferredTransitionIfNeeded:] + 422
10 UIKit 0x27a2a931 -[UINavigationController __viewWillLayoutSubviews] + 44
11 UIKit 0x27a2a8c9 -[UILayoutContainerView layoutSubviews] + 184
12 UIKit 0x2797f25f -[UIView layoutSublayersOfLayer:] + 514
13 QuartzCore 0x273aa1d5 -[CALayer layoutSublayers] + 136
14 QuartzCore 0x273a5bd1 <redacted> + 360
15 QuartzCore 0x273a5a59 <redacted> + 16
16 QuartzCore 0x273a5447 <redacted> + 222
17 QuartzCore 0x273a5251 <redacted> + 324
18 UIKit 0x27980c31 <redacted> + 1384
19 CoreFoundation 0x244ca807 <redacted> + 14
20 CoreFoundation 0x244c9c1b <redacted> + 222
21 CoreFoundation 0x244c8299 <redacted> + 768
22 CoreFoundation 0x24415db1 _CFRunLoopRunSpecific + 476
23 CoreFoundation 0x24415bc3 _CFRunLoopRunInMode + 106
24 GraphicsServices 0x2b7a0051 _GSEventRunModal + 136
25 UIKit 0x279e0f01 _UIApplicationMain + 1440
This also happens when for some reason you push the segue / viewcontroller multiple times. One of such case is when you are observing for a notification and if for some reason that notification was posted multiple times and in the observing method, if you were pushing a view controller, it will push to more than once which eventually will cause this kind of crash.
Sorry for being late for the party. I recently had this issue wherein my navigationbar goes into corrupted state because of pushing more than one view controller at the same time. This happens because the other view controller is pushed while the first view controller is still animating. Taking hint from the nonamelive answer from here
I came up with my simple solution that works in my case. You just need to subclass UINavigationController and override the pushViewController method and check if previous view controller animation is finished as yet. You can listen to the animation completion by making your class a delegate of UINavigationControllerDelegate and setting the delegate to self.
I have uploaded a gist here to make things simple.
Just make sure you set this new class as the NavigationController in your storyboard.
I am trying to display a view that contains details of the user's account. Being fairly new to iOS development, the following code is what should work (based the docs and searches). Yet, the application crashes and I get a an error stating unrecognized selector:
2012-03-13 16:32:25.616 UrbanAgendaApp[4993:207] Displaying profile view
2012-03-13 16:32:25.635 UrbanAgendaApp[4993:207] -[UAFirstViewController presentViewController:animated:completion:]: unrecognized selector sent to instance 0x4b45240
2012-03-13 16:32:25.674 UrbanAgendaApp[4993:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UAFirstViewController presentViewController:animated:completion:]: unrecognized selector sent to instance 0x4b45240'
*** Call stack at first throw:
(
0 CoreFoundation 0x00fbabe9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0110f5c2 objc_exception_throw + 47
2 CoreFoundation 0x00fbc6fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00f2c366 ___forwarding___ + 966
4 CoreFoundation 0x00f2bf22 _CF_forwarding_prep_0 + 50
5 UrbanAgendaApp 0x00002308 -[UAFirstViewController showProfileView] + 168
6 UrbanAgendaApp 0x00002254 -[UAFirstViewController myUaBtnTouch:] + 52
7 UIKit 0x00014a6e -[UIApplication sendAction:to:from:forEvent:] + 119
8 UIKit 0x000a31b5 -[UIControl sendAction:to:forEvent:] + 67
9 UIKit 0x000a5647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
10 UIKit 0x000a41f4 -[UIControl touchesEnded:withEvent:] + 458
11 UIKit 0x000390d1 -[UIWindow _sendTouchesForEvent:] + 567
12 UIKit 0x0001a37a -[UIApplication sendEvent:] + 447
13 UIKit 0x0001f732 _UIApplicationHandleEvent + 7576
14 GraphicsServices 0x00cbea36 PurpleEventCallback + 1550
15 CoreFoundation 0x00f9c064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
16 CoreFoundation 0x00efc6f7 __CFRunLoopDoSource1 + 215
17 CoreFoundation 0x00ef9983 __CFRunLoopRun + 979
18 CoreFoundation 0x00ef9240 CFRunLoopRunSpecific + 208
19 CoreFoundation 0x00ef9161 CFRunLoopRunInMode + 97
20 GraphicsServices 0x00cbd268 GSEventRunModal + 217
21 GraphicsServices 0x00cbd32d GSEventRun + 115
22 UIKit 0x0002342e UIApplicationMain + 1160
23 UrbanAgendaApp 0x00001c2a main + 170
24 UrbanAgendaApp 0x00001b75 start + 53
25 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
The method where this occurs is in a method in FirstViewController, which gets called as a result of a touch up event inside a button:
-(void)showProfileView {
NSLog( #"%#", #"Displaying profile view" ); // ***
UAProfileView *profileView = [[UAProfileView alloc] init];
[self presentViewController:profileView animated:TRUE completion:0];
}
This UAProfielView is a subclass of UIViewController and was was created along with an appropriate .xib file.
So the question is, how do I display this new view in my iPhone application? Using a storyboard is not an option because I have to support iOS 4.0.
The documentation for presentViewController:animated:completion: states that it is only supported on iOS 5.0 and up. You mentioned support for iOS 4.0.
Try presentModalViewController:animated: instead. Alternatively, use a nagivationController and do pushViewController:animated:
#Mike, make sure you connected the nib to the file's owner.
Presumably, the base class of UAFirstViewController is also UIViewController? Are you getting any warnings when you build?
I would personally use completion:nil, but I don't think that will make a difference.
So, if you are getting no warnings, then turn zombies on and see if you are dealing with a dead object. Instructions are here
How to enable NSZombie in Xcode?
Run the program and see if you get a zombie warning in the console. If that's the case, then the memory management is wrong.
If all of that is ok, post the code where you call showProfileView.