Application crashing without information about crash when transitioning to another view controller - swift

I have two view controllers, LoginViewController and TermsAndPrivacyViewController.
On first view controller, there is a button that has IBAction, which opens TermsAndPrivacyViewController. On TermsAndPrivacyViewController I have web view, that loads url I am passing from LoginViewController. So, this is the code(Login view controller):
#IBAction func tosAction(_ sender: Any) {
if let vc = UIStoryboard(name: "Login", bundle: nil).instantiateViewController(withIdentifier: kTOSViewControllerIdentifier) as? TermsAndPrivacyViewController{
vc.url = URL(string: kTOSUrl)
self.navigationController?.pushViewController(vc, animated: true)
}
}
On TermsAndPrivacyViewController, I have this:
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
if let `url` = url {
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
}
}
So, when I hit a button, app crashes SIGABRT message, and nothing else. Also, I don't get any crash report on Firebase Crashlytics (I have detached an app from a debugger first, and produced a crash).
Now, the strange part :/ ... If I put a breakpoint on a first line of tosAction() method, and go step by step (or just let it continue), everything works normally. No crash???
Am I missing something obvious here? What is the reason of crashing? Also, I tried to put Exception Breakpoint but nothing changes. I only get this:
and a console:
so, kinda no information about crash at all.
EDIT
Ok, now the even more strange part :) I just tried app on different phones.
App crashes on iPhone 6s+, iOS 12.1(16B5059d), but it works normally on iPhone 6, iOS 12.0 (16A366)

maybe you use library or framework that not supported by those device.
you must see the error
did you try this?
when the app crashing, in the console press cmd+F and search exception.
now you can see your error
hope to helpful.

Maybe you can use segue methods inside your LoginViewController.
#IBAction func tosAction(_ sender: Any) {
performSegue(withIdentifier: "GoToWeb", sender: nil)
}
}
And call prepareForSegue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "GoToWeb") {
let vc = segue.destination as! TermsAndPrivacyViewController
vc.url = "YOUR_URL"
}
And the code inside TermsAndPrivacyViewController don't change
Edit:
Maybe your not binding well your UIButton, can you verify in the right panel, in the section "Show the connection inspector" if your button is call only once.

To get further information on this type of crashes, open the Breakpoints menu (or press CMD+8), click the plus icon in the bottom left corner and press Exception Breakpoint.... Right click, then edit. Add an action of the type Debugger Command and enter the following:
Reproduce the crash again, this time the console will output a more useful error message.

Related

Unknown class QuoteDetailViewController in Interface Builder file with Xcode 12

I saw a lot of posts about this error in Xcode but all of them are quite old. I'm learning how to code in Swift and I'm following the instruction of book.
My Xcode is version 12.5.1. The goal of this app is to display a list of quotes (string) and when I tap on one of them, display a new view that has as a title the quote.
I have a very simple storyboard. There is a TableView with a segue to a View. I created a new Cocoa file for tableview. TableView is working.
I connect the TableView with the View.
I repeated the some process for the View. I added a new Cocoa file called QuoteDetailViewController, click on top of the view and in the Class I selected from the list the file.
When I run the application in the iPhone 11 simulator, the view doesn't have any quote as title. I put a breakpoint in the code connected to the TableView and the app stops there. If I put a breakpoint in the QuoteDetailViewController nothing happens but I see an error in the output
2021-08-11 19:13:17.215204+0100 QuoteApp[80238:4055489] [Storyboard] Unknown class QuoteDetailViewController in Interface Builder file.
The QuoteDetailViewController is very basic.
import UIKit
class QuoteDetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let quoteViewController = segue.destination as? QuoteDetailViewController {
if let selectedQuote = sender as? String {
quoteViewController.title = selectedQuote
}
}
}
}
I tried to build again and again the app. I tried to Clean Build Folder and build again. I tried to recreate the View and the code. After all of that, nothing changed. The error is still there.
The source code is on GitHub.
Update
If I click on the arrow at the end of Class and just before the dropdown, Xcode opens the file I expect to be opened.
Select the QuoteDetailViewController, open Side Inspector view and Update the Target Membership same as QuoteTableViewController
Select the controller On the Storyboard, and Add it to the module.
Check Screenshots for reference:
So, I said that in the QuoteDetailViewController I have this code.
import UIKit
class QuoteDetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let quoteViewController = segue.destination as? QuoteDetailViewController {
if let selectedQuote = sender as? String {
quoteViewController.title = selectedQuote
}
}
}
}
The error was that the function prepare must be in the QuoteTableViewController.

NavigationController nested in TabController animation bug

I try my best to explain what is happening.
I have updated the XCode to Version 10.1 (10B61)
And the iOS on my iPhone and Simulator is v12.1
My app has a TabController with 5 tabs.
First: Posts
Fifth: Profile Posts
These are embedded into a navigation controller (In case someone
clicks on the comments button)
So. I've noticed that if I run my app and I click the comments, it pushes that vc in a weird way to the screen, then clicking back just "bumps" back. Also slide back isn't working.
However, if I switch tabs first then everything works fine.
VIDEO:
https://www.youtube.com/watch?v=fgS3j21L8Js
As you see in the video everything is fine after switching to Profile Posts + back .
UPDATE 1:
So if I start my app, switch to another Tab, then back to the original, it works fine.
Requested code:
func commentsButtonTapped(sender: UIButton) {
let touchPoint:CGPoint = sender.convert(CGPoint.zero, to:self.tableView)
if let indexPath = tableView.indexPathForRow(at: touchPoint) {
openDetails(indexPath: indexPath, shouldShowKeyboard: false)
}
}
func openDetails(indexPath: IndexPath, shouldShowKeyboard : Bool) {
if (self.tableView.cellForRow(at: indexPath) as? WorldMessageCell) != nil {
let storyboard = UIStoryboard(name: "Additional", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "DetailsViewController") as! DetailsViewController
vc.postId = PostIds.shared.nearby.ids[safe: indexPath.row]
vc.shouldShowKeyboard = shouldShowKeyboard
self.navigationController?.pushViewController(vc, animated: true)
}
}
UPDATE 2:
Solved the problem by forcing the TabController to switch between tabs..
override func viewDidAppear(_ animated: Bool) {
self.selectedIndex = 1
self.selectedIndex = 0
}
But that's not how it should work..
UPDATE 3:
I have tested it, if I make the navigation controller->vc the initial vc (so no tab controller) everything works fine.
But as soon as the navigationcontroller is nested inside the tab, it happens.
I made a new project to test if this is a version specific bug but no, everything works fine there. So the issue must be with my app.
What could generate issue like that (in the video)?
Ohh.. I have found the problem & bug:
So if you have navigation controllers nested into a tab controller that calls it's viewDidLoad() function, then the navigation controller will have problems.
The code I had to remove totally:
override func viewDidAppear(_ animated: Bool) {
// here i had some code ... /
}
Now everything works..

iOS QR code scanner triggering actions multiple times

I am using the QR code reader code from AppCoda (http://www.appcoda.com/qr-code-reader-swift/#comments) and converted it to Swift 3. The base code works perfectly fine.
However, what I want to achieve is to retrieve a String from the QR reader, store it in a variable, and pass the variable to a following view controller. So I added a bit of code to it to get the following:
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
if metadataObjects == nil || metadataObjects.count == 0 {
qrCodeFrameView?.frame = CGRect.zero
messageLabel.text = "No barcode/QR code is detected"
return
}
let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
if supportedBarCodes.contains(metadataObj.type) {
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
qrCodeFrameView?.frame = barCodeObject!.bounds
if metadataObj.stringValue != nil {
messageLabel.text = metadataObj.stringValue
}
//
//
// CODE I ADDED STARTS BELOW
//
performSegue(withIdentifier: "showMenu", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showMenu"{
let tabVc = segue.destination as! UITabBarController
let navVc = tabVc.viewControllers?.first as! UINavigationController
let menuVc = navVc.viewControllers.first as! MenuViewController
menuVc.qrScan = self.messageLabel.text
}
It actually achieves what I wanted it to do, but it somehow triggers the "performSegue" multiple times. The transition animation of the first segue goes halfway, and then the second one happens.
The segue "showMenu" is a manual segue connected from the view controller of the QR Reader view to a tab bar controller that houses a navigation controller and Menu view controller.
Things I've tried:
Print the passed on variable in the viewdidload function of Menu view controller. The string gets printed out twice.
Added a hidden button on the QR reader view and change the segue connection of "showMenu" from the view controller to the button. Removed perform segue from code. While holding the camera in place to scan qr codes, pressing the button performs the intended function and the segue is only triggered once.
With the same setting as (2), I programmatically trigger the button by using a touch up inside event when a qr code is scanned. The segue gets triggered twice.
Added breakpoints for performSegue and the if clause right above it. After I scan something, and press the "continue program execution" button, the program loops between the two breakpoints on and on.
If anyone can enlighten me a bit over here, I would be very grateful. Thanks a bunch for the help in advance.
The issue was fixed by adding the following line of code after the segue was performed:
self.captureSession?.stopRunning()
However, the question of why doesn't unwind segue have a similar issue still remains.
I've just solved the same problem. You have to create an unwind to the previous view.
To do this in the interface builder, you have to ctrl-drag from the controller to the exit in the controller you're actually in (not the one you want to unwind).
Once you have done this, you have to set an identifier to this unwind segue (in your case "showMenu". To do this, you have to the unwind segue from the scenes menu on the left part and set the identifier name on the Attributes inspector.

No Segue with Identifier Error in Swift?

I am trying to use the performSegueWithIndentifier function to to create a segue from one ViewController to the next. But, when I press the button with the UITApGestureRecognizer connected to it, the View shifts to the debugger panel.
Here is the error it is displaying:
ContaminateTargetViewController: has no segue with identifier 'showMasterChemistryViewController'
(I cut out the personal Info)
Here is the ViewControllers Class:
import Foundation
import UIKit
class ContaminateTargetViewController: UIViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showMasterChemistryViewController" {
let chemistryMasterViewController = segue.destinationViewController as! ChemistryMasterViewController
}
}
#IBAction func showPlaylistDetail(sender: AnyObject) {
performSegueWithIdentifier("showMasterChemistryViewController", sender: sender)
}
}
I also previously had to manual segues from the 2 buttons I have on the ViewController and recently deleted them to switch over to the UITapGestureRecognizer for the convenience. I am wondering if I have an error in my code that I do not see or if previously deleting the manual segues from the View is causing this error. If the problem is rooting from the previously deleted manual segues please tell me how to fix this in your error. If the problem is rooting form the code, please leave the code I should add, delete, or substitute.
Any suggestions or input is greatly appreciated.
Thanks in advance.
This error is called when you do not have the requested segue connected to your view controller. Are you sure that you have the two view controllers connected via a segue named "showMasterChemistryViewController" on your storyboard?

App crashes on segue after embedding view controllers

I have a segue that works fine when it is directly from a UIViewController to a UITableViewController, but when I embed the second view in a navigation controller, the segue no longer seems to work and I get unexpectedly found nil while unwrapping optional error. I don't believe I need to change the code. Should I rebuild the app somehow? I've read about errors in Xcode 6 beta (though I'm using 6.1) that cause the order in which a developer builds the app to have an effect.
Because destination of your segue is not as NavigationController. You must set the controller as NavagationController first.
Try this code
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "showItemSegue") {
let controller: Your_TableViewController = (segue.destinationViewController as UINavigationController).topViewController as Your_TableViewController
}
}
I hope this work