Unrecognized selector sent to instance for Bar Button - swift

I'm making a Twitter app on Xcode and have encountered a frustrating error.
I'm tryna make the Tweet bar button present modally.
When I run the code it crashes if I click "Tweet"
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Twitter.TweetViewController _finishDecodingLayoutGuideConnections:]: unrecognized selector sent to instance 0x7fb1a25512c0'
*** First throw call stack:
libc++abi.dylib: terminating with uncaught exception of type NSException
import UIKit
class TweetViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBOutlet weak var tweetTextView: UITextView!
#IBAction func cancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func Tweet(_ sender: Any) {
if (!tweetTextView.text.isEmpty) {
TwitterAPICaller.client?.postTweet(tweetString: tweetTextView.text, success:{ self.dismiss(animated: true, completion: nil)
}, failure: { (error) in
print("Error posting tweet \(error)")
self.dismiss(animated: true, completion: nil)
})
} else {
self.dismiss(animated: true, completion: nil)
}
}
I looked up people with similar issues but could not find an solution that helped.

Verify the IBOutlets and IBActions are properly connected. These crash happens when the XIB and Class files are not properly connected.
Try to remove the connections and add it again. Also rename the property names if the error persist.

Related

I get Thread 1: signal SIGABRT and my IOS App crashes

I am working on an IOS App on Swift and its connected to Firebase. Once I reach a specific page in the run mode, my app crashes and I get this error message without any details. Please help
I do not have any errors with my Outlets and I have tried debugging with break points but it still takes my to the AppDelegate with this error without details. I am clueless. Before it used to work the code should be fine and data were being inputted to the DB but something happened since I have created the login page.
// LoginViewController.swift
// Together
import UIKit
import Firebase
class LoginViewController: UIViewController {
#IBOutlet weak var usernameTxt: UITextField!
#IBOutlet weak var passTxt: UITextField!
#IBAction func userLoginBtn(_ sender: Any) {
var pass = passTxt.text
Auth.auth().signIn(withEmail: usernameTxt.text!, password: passTxt.text!){
(user, error) in
if error == nil{
self.performSegue(withIdentifier: "loginToHome", sender: self)}
else{
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
I GOT THIS ISSUE SORTED FINALLY and The mistake was very simple. If anyone is facing the same issue and you are sure you don't have any issues with your outlets, go the to Identity inspector and check the Class of each ViewController. Make sure not more than 1 ViewController is connected to the same Class, especially if the class had code for a specific function. This was the reason why my App crashes and takes me to the AppDelegate class. The code of the last page I reach before the crash did not have errors, but the only cause was having it connected to a Class used by another ViewController.

Custom UIAlertController - Application tried to present modally an active controller

Application tried to present modally an active controller
I'm trying to create custom UIAlertController.
Thus from different places will be easier to work with.
but I'm getting this error :
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller
class CustomAlert: UIAlertController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
private static var sheet : UIAlertController = UIAlertController()
static let instance = CustomAlert()
func create(title: String, message: String) -> CustomAlert {
CustomAlert.sheet = UIAlertController(title: title, message: message, preferredStyle: .actionSheet)
return self
}
func addlibrary() -> CustomAlert{
let libraryAction = UIAlertAction(title: "library", style: .default, handler: nil)
CustomAlert.sheet.addAction(libraryAction)
return self
}
func show(on vc : UIViewController){
UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)
}
}
Where is the problem?
Thanks
You are trying to present the wrong controller in your show method.
Change:
UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)
to:
vc.present(self, animated: true, completion: nil)

UIButton does not bring up MFMailViewController

I'm having an error with a bit of code. I am new to this and I am trying to teach myself. I am finding most of my answers online but can't seem to find anything about this particular issue. I want to send an email within the app but anytime I press the email button, the MFMailViewController does not come up. It is like my UIButton isn't working. But I know I have it as an IBAction. Here is my code so far. Any help is much appreciated.
import UIKit
import MessageUI
class RequestService: UIViewController,MFMailComposeViewControllerDelegate {
#IBOutlet weak var CustomerName: UITextField!
#IBOutlet weak var emailButton: UIButton!
#IBAction func sendEmail(_ sender: UIButton) {
if !MFMailComposeViewController.canSendMail() {
print("Mail services are not available")
let ComposeVC = MFMailComposeViewController()
ComposeVC.mailComposeDelegate = self
ComposeVC.setToRecipients(["jwelch#ussunsolar.com"])
ComposeVC.setSubject("New Support Ticket")
ComposeVC.setMessageBody(CustomerName.text!, isHTML: false)
self.present(ComposeVC, animated: true, completion: nil)
}
func mailComposeController(controller: MFMailComposeViewController,didFinishWithResult result:MFMailComposeResult, error: NSError?) {
// Check the result or perform other tasks.
// Dismiss the mail compose view controller.
controller.dismiss(animated: true, completion: nil)
}
}
}
You made an error in the syntax in your sendMail function. The code you posted will only open the view controller if the device can't send mail. Change it to this:
#IBAction func sendEmail(_ sender: UIButton) {
if !MFMailComposeViewController.canSendMail() {
print("Mail services are not available")
return
}
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = self
composeVC.setToRecipients(["jwelch#ussunsolar.com"])
composeVC.setSubject("New Support Ticket")
composeVC.setMessageBody(CustomerName.text!, isHTML: false)
self.present(composeVC, animated: true, completion: nil)
}
You only attempt to display the mail controller if the device can't send email. That's backwards.
#IBAction func sendEmail(_ sender: UIButton) {
if MFMailComposeViewController.canSendMail() {
print("Mail services are not available")
let ComposeVC = MFMailComposeViewController()
ComposeVC.mailComposeDelegate = self
ComposeVC.setToRecipients(["jwelch#ussunsolar.com"])
ComposeVC.setSubject("New Support Ticket")
ComposeVC.setMessageBody(CustomerName.text!, isHTML: false)
self.present(ComposeVC, animated: true, completion: nil)
}
}
func mailComposeController(controller: MFMailComposeViewController,didFinishWithResult result:MFMailComposeResult, error: NSError?) {
// Check the result or perform other tasks.
// Dismiss the mail compose view controller.
controller.dismiss(animated: true, completion: nil)
}
And you need the delegate method outside of the other method.

Swift - Trying to set up a share button

I'm trying to set up a share button from a time I previously coded it. I must be missing something, but I'm not sure what. Can you help? This is on a different view controller than the main one.
import UIKit
class MoreViewController: UIViewController, UITabBarDelegate, UITextFieldDelegate {
#IBAction func shareKnockingBuddy(_ sender: AnyObject) {
let messageToSend = "Here is a message. \(doorsKnocked)"
let vc = UIActivityViewController(activityItems: [messageToSend], applicationActivities: nil)
self.present(vc, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Here's my error: On the App delegate it's "Thread 1: signal SIGABRT". On the message thingy on the bottom, it says "* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController shareKnockingBuddy:]: unrecognized selector sent to instance 0x7fe282c02eb0'
* First throw call stack:"
Notice the error is about UIViewController and not your MoreViewController class. This means you did not set th proper class name for the view controller in your storyboard. Change it to MoreViewController.

Sending an email from an app using MFMail

I'm trying to make my app able to access and send an email after a button is pressed. This is what I have so far and when I run it, and click the help button the alert pops up and the cancel button works fine but the email part of the alert crashes the app.
When it crashes it highlights the class AppDelegate: UIResponder, UIApplicationDelegate line and says Thread 1: signal SIGABRT.
#IBAction func helpButtonAction(sender: UIButton) {
let alert = UIAlertController(title: "Help", message: "Click 'Email' to email support", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Email", style: UIAlertActionStyle.Default, handler: { action in
let emailTitle = "Help Request"
let messageBody = ""
let toRecipents = ["sample#sample.com"]
let mc: MFMailComposeViewController = MFMailComposeViewController()
mc.mailComposeDelegate = self
mc.setSubject(emailTitle)
mc.setMessageBody(messageBody, isHTML: false)
mc.setToRecipients(toRecipents)
self.presentViewController(mc, animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
self.dismissViewControllerAnimated(false, completion: nil)
}
Heres the console error...
'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target <app.ViewController: 0x13c64a5f0>.'
*** First throw call stack:
(0x183930f48 0x19847ff80 0x18923def4 0x189240800 0x188fbdea0 0x10004909c 0x1000491d0 0x100048cbc 0x100048d0c 0x1893297d8 0x189329f70 0x189218ba4 0x18921bd9c 0x188ff3668 0x188eff240 0x188efed3c 0x188efebc4 0x1886c5c2c 0x1013d5c68 0x1013db710 0x1838e81f8 0x1838e6060 0x183814ca0 0x18e87c088 0x188f2cffc 0x10004ee78 0x198cc28b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
The problem is how you are instantiating a View Controller.
This code will instantiate the class, but not the view as you want to.
let mc: MFMailComposeViewController = MFMailComposeViewController()
The proper way to do so, can be found in the link above, i will just copy the code here.
You must set an identifier to your view controller, instantiating it by the storyboard, and then, presenting it.
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
self.presentViewController(vc, animated: true, completion: nil)
Instantiate and Present a viewController in Swift