UIPresentationController crash just points to AppDelegate
Asked Answered
I

4

4

Screenshots :

enter image description here


enter image description hereI am getting a lot of these crashes but the problem is I'm just being pointed to my appDelegate first line. I've no idea where to look for the issue. Any ideas where I could start to investigate from the following crash report?

Crashed: com.apple.main-thread
0  UIKit                          0x18d005640 __56-

[UIPresentationController runTransitionForCurrentState]_block_invoke + 460
1  UIKit                          0x18cf27aa8 _runAfterCACommitDeferredBlocks + 292
2  UIKit                          0x18cf1ae5c _cleanUpAfterCAFlushAndRunDeferredBlocks + 288
3  UIKit                          0x18ccac464 _afterCACommitHandler + 132
4  CoreFoundation                 0x1836a6cdc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
5  CoreFoundation                 0x1836a4694 __CFRunLoopDoObservers + 412
6  CoreFoundation                 0x1836a4c50 __CFRunLoopRun + 1292
7  CoreFoundation                 0x1835c4c58 CFRunLoopRunSpecific + 436
8  GraphicsServices               0x185470f84 GSEventRunModal + 100
9  UIKit                          0x18cd1d5c4 UIApplicationMain + 236
10 AppName                        0x100ae3ca4 main (AppDelegate.swift:23)
11 libdyld.dylib                  0x1830e456c start + 4

Update:

Based off the following:

App crashing on runTransitionForCurrentState but no clue as to why

I'm looking at potential causes and am wondering about the following code.

I have the following func for presenting a view with an activity indicator while I am doing a sync process.

public func displayActivityAlertWithCompletion(_ title: String, ViewController: UIViewController, completionHandler: @escaping ()->())
{
    let pending = UIAlertController(title: "\n\n\n"+title, message: nil, preferredStyle: .alert)
    //create an activity indicator
    let indicator = UIActivityIndicatorView(frame: pending.view.bounds)
    indicator.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    indicator.color = UIColor(rgba: Palette.loadingColour)
    //add the activity indicator as a subview of the alert controller's view
    pending.view.addSubview(indicator)
    indicator.isUserInteractionEnabled = false
    // required otherwise if there buttons in the UIAlertController you will not be able to press them
    indicator.startAnimating()


    ViewController.present(pending, animated: true, completion: completionHandler)
}

I then use this func like so:

displayActivityAlertWithCompletion("Pushing Data", ViewController: self){_ in
    Helper_class.doSync(_cleanSync: false){
        //sync is complete
        Prefs.is_Syncing = false
        DispatchQueue.main.async {
            //dismiss my view with activity alert
            self.dismiss(animated: true){
                //dismiss my viewcontroller
                Toast(text: "Upload sync completed").show()
                self.dismiss(animated: true, completion: nil)
            }
        }
    }
}

Would this be a potential cause for the UIKit issue?

Inesinescapable answered 13/2, 2018 at 10:42 Comment(19)
How do you know it's the presentation controller which is causing the issue ?Baines
@Baines I thought that was it based off the first line of the crash report?Inesinescapable
Did you try putting a breakpoint so that you get to know which line of code is causing the issue ?Baines
@Baines Where would I start to look to know where to add the breakpoint? My app is huge. over 150 view controllers.. I haven't seen this issue myself, I am just getting crash reports on it from external usersInesinescapable
In that case, my first suggestion would be to integrate a crash reporting tool like Crashlytics . It gives yo a detailed crash report with the line number and class which is causing the crashBaines
@Baines the crash report above, is from crashlytics but it just points to the first line of my appDelegateInesinescapable
Based on my experience Crashlytics always gives the name of the file which is the source of crash. Can you share a screenshot of crashlytics website page which shows this crash report ?Baines
@Baines I usually get line numbers also, but just not for this particular crash. Ive added a screenshot to the QInesinescapable
Also check if this helps - #39530625Baines
@Baines thanks for the link. I'm trying to understand where I am doing something with dismissals/presentations which might be problematic. I updated the q to include a function which I am wondering is completely safeInesinescapable
I have no idea why you are dismissing twice.Baines
Just use this once : self.dismiss(animated: true, completion: nil)Baines
Another thing : Is the issue replicable at your end ? My point being, if you fix this, how would you test that ?Baines
@Baines the first dismiss, dismisses UIAlertController and the second dismisses UIViewController. I need two but maybe there's a better way to do this and this is periodically causing a crash in UIKit? I've no idea if this is the root, it's just a question. Unfortunately, no the issue isn't replicable for me. This is why I'm trying to reach out to people who may have a more in-depth knowledge of UIKit. All I can do is make changes, close the crash on crashlytics and see if it pops up againInesinescapable
Since you are dismissing alertController from outside the scope of it's button. You should take pending as the global variable and dismiss it using pending.dismiss------ and then in the completion handler dismiss self.dismiss-------Baines
@Baines Could you update your answer to explain the alternate approach to dismiss the alertcontroller based off the function used in my Q? e.g. I'm unsure where this global variables is defined? in my VC? Do you think this may be the root of my original issue?Inesinescapable
Updated my answer.Baines
How did you fix this bug?Sulfonal
@Sulfonal It was linked to presenting a view controller from one which is being dismissed, so you have to go through all of your presenting and dismiss code and make sure you have proper completion handlers in every caseInesinescapable
B
5

Follow these steps, you can make it: 1. Open Navigator; 2. Switch to BreakPoint Navigator; 3. Click the "+" button in the bottom left; 4. When pop up, click "Exception BreakPoint".

Then run your project again, it will break at the exact point.

Brewmaster answered 13/2, 2018 at 10:57 Comment(0)
B
1

Following are my suggestions :

  1. Try to replicate the issue yourself. Since you know which screen has the crash, you could easily identify the viewcontroller/class causing the crash. That would be a good start. Once yo have identified the class, check
    • If the crash occurs while the screen is loading or leaving the screen. Put breakpoints on UIViewController functions - viewDidLoad, viewWillAppear, viewWillDisappear and so on.
    • If crash occurs on an event like button tap, segment change or table reload.
  2. Get more information from Crashlytics report. It always comes with the file name where crash had occurred. I have attached a Crashlytics screenshot which shows list of crashes along with file name.
  3. Update your question with more information after you conduct the above.

enter image description here

As per the your code, you are dismissing the same viewController twice. Take pending as a global variable. And dismiss it as :

pending.dismiss(animated: true, completion: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(0.1)) {
    self.dismiss(animated: true, completion: nil)  // This will be called after above time gap.
}
Baines answered 13/2, 2018 at 11:8 Comment(14)
I have followed LiuYanfeng's suggestion with the breakpoints and I will try and go in and out of all screens but I've never got this crash when developing. I just see it come in from other users. I've shared the screenshot but from what I see it just points to appDelegate line 23 (this is the first line of the file after copyright and imports)Inesinescapable
Thank you for the help. Maybe I'm missing something. I've added a second screenshot which shows UIPresentationController and not any line number from my filesInesinescapable
so pass back pending from public func displayActivityAlertWithCompletion(_ title: String, ViewController: UIViewController, completionHandler: at.escaping ()->()) ?Inesinescapable
You are calling displayActivityAlertWithCompletion from the same class ?Baines
no this func is in a separte file and is used across multiple VCsInesinescapable
Then yes, it is better to pass alertController instance hereBaines
I tried returning back UIAlertController and then using let pending = displayActivityAlertWithCompletion2(".... but then when trying to call pending.dismiss in the completion I have the error variable used within its own initial valueInesinescapable
Make the function declaration as : public func displayActivityAlertWithCompletion(_ title: String, ViewController: UIViewController, pending: UIAlertController, completionHandler: @escaping ()->())Baines
Ok so define UIAlertController every time before using this func, do you think this has the potential to be linked to the original crash?Inesinescapable
I guess, but I cannot promise this. Since I have zero percent idea where exactly this crash is happening. But yes, this is a potential fix. Few steps : 1) Confirm the above change by running locally. 2) Try getting in touch with the user if possible who has faced this issue. 3) Use Crashlytics to see the details of device and try running the app on the same compatible deviceBaines
thanks for all the help. I've already re-tested on the same devices as those linked to the crash. It's happening across multiple device types but never for me when developing. But I can make the changes and close out the issue and see if it re-appearsInesinescapable
Ok. Another suggestion - Check for same code at other places or where you are presenting a UIViewController or UIAlertController.Baines
thanks, the problem is that a search of .present( in my project returns 151 results and .dismiss( returns 371 results :/Inesinescapable
The best deal would be to try to get in touch with some user. You can yourself install the app for that matter. And start using it from top to bottom. You can ask your friends as well to start using it. Trust me, that would help.Baines
C
0

I had an issue with a crash in the UIPresentationController constructor when doing some migration some year.

For me, the issue was solved by changing presenting to source in the UIViewControllerTransitioningDelegate.

Like:

public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
    return PresentationController(presentedViewController: presented, presenting: source)
}

Though it was reproducible all times, so perhaps not the same issue..

Carnatic answered 13/2, 2018 at 11:50 Comment(0)
S
0

I encountered the same crash. And I reproduced this crash by this case. There is a viewController was presented. The crash happens when I use this viewController to present another viewController while this viewController is being dismissed with animation. I think you can add some condition to avoid this case such as judging if the viewContoller.isBeingDismissed. If isBeingDismissed is true, use other viewControllers to do present action.

Sprue answered 31/7, 2018 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.