"performSegueWithIdentifier" gives fatal error - ios

I am new in iOS-Swift. I created simple app, first time after log in "performSegueWithIdentifier" works fine but After logout I'm coming back to root view controller if I again log in, "performSegueWithIdentifier" gives me fetal error (crash). I am not setting any property from my login view. I don't understand y its working fine for the first time and gives error second time.
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.login()
}
func login() {
if user == nil {
self.presentViewController(logInView, animated: false, completion: nil)
} else {
self.performSegueWithIdentifier("Home", sender: self) // Here I m getting error after logout when i log in again.
}
}
in my second view, after logout i have written this:
self.navigationController?.popToRootViewControllerAnimated(false)
Error I get is the following:
fatal error: unexpectedly found nil while unwrapping an Optional value
My storyboard hierarchy is:
Navigation controller - ViewController(loginview)- TabbarController(HomeView)- Four tabs Two view controllers and two TableViewControllers.
From one of the TableViewController I am calling method
self.navigationController?.popToRootViewControllerAnimated(false)
Then its coming back to ViewController(loginview) but if i again try to login that time Tabbar view controller is not present. i m getting this by following code:
print("NextView = (storyboard.instantiateViewControllerWithIdentifier("Home"))") // Here only i m getting fetal error.

You can change the root view controller like this:
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) // "Main" is storyboard name
let viewController = mainStoryboard.instantiateViewControllerWithIdentifier("id") as UITabBarController
UIApplication.sharedApplication().keyWindow?.rootViewController = viewController;

Related

Error passing value to view controller on dismiss | Swift 5

Error transferring value from one view controller to another on dismiss.
I have a value in ViewController2 that I would like to transfer to ViewController1 on dismiss. In view ViewController2 I do the following to dismiss:
func OtherFunction() {
passAndDismiss(scannedScript: stringCodeValue)
}
Note: stringCode value is indeed being passed as a String to scannedScript
func passAndDismiss(scannedScript: String) {
dismiss(animated: true, completion: {
let viewcontroller = ViewController1()
viewcontroller.Textfield1.text = scannedScript
})
}
The error occurs on line:
viewcontroller.Textfield1.text = scannedScript
The error I get is:
Unexpectedly found nil while implicitly unwrapping an Optional value
Two fatal issues:
ViewController1() is a new instance of the controller which is not the instance in the storyboard.
Solution: You need the real instance either with a segue or with instantiation from the storyboard.
Even if ViewController1() was the expected controller the outlets are not connected right after the initialization.
Solution: You have to declare a temporary property for the string in ViewController1 and assign the value to the label in viewDidLoad
Here you are initialising viewcontroller with wrong way. You should load from xib or storyboard.
In your way not initialise xib or storyboards’ ui element objects. Here textfield object nil and you are trying to access text property of that. That’s why app crashed. You should use following way:
let myViewController = MyViewController(nibName: "MyViewController", bundle: nil)
OR
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
If you are not using xib or storyboard then please initialise textfield object in that controller’s init method

Swift : fatal error: unexpectedly found nil and EXC_BAD_INSTRUCTION

I m new to Xcode and i m building a project with a login button. After clicking the login with details in the text field, it will redirect to the second view which is the scroll view controller. However, i got two parts of "Error"
Normally, it work with a normal view controller(login and move to the second view). I have just recreate a view controller to a scroll view controller and it did not work.
By the way, I got a build success but i just got error when i try to "login"
Can anyone explain why i got the thread error and the fatal error?
How can i resolve the problem?
login view Controller
#IBAction func LoginBtn(sender: AnyObject) {
LoginIn()
}
func LoginIn(){
let user = PFUser()
user.username = usernameTF.text!
user.password = passwordTF.text!
PFUser.logInWithUsernameInBackground(usernameTF.text!,
password:passwordTF.text! , block: { (User: PFUser?, Error
:NSError? ) -> Void in
if Error == nil{
dispatch_async(dispatch_get_main_queue()){
let Storyboard = UIStoryboard(name: "Main", bundle: nil)
let MainVC : UIViewController = Storyboard.instantiateViewControllerWithIdentifier("scrollV") as UIViewController
self.presentViewController(MainVC, animated: true, completion: nil)
}
}
else{
NSLog("Wrong!!!!")
}
})
}
Scroll View Controller
import UIKit
class ScrollViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
let V1 : ScrollViewController = ScrollViewController(nibName: "ScrollViewController", bundle: nil)
self.addChildViewController(V1)
self.scrollView!.addSubview(V1.view!)
V1.didMoveToParentViewController(self)
}
You are doing some forced unwrapping, which is not recommended (in general forced stuff in Swift is not recommended), and it will crash your application if the variable being unwrapped is nil. That's why forced unwrap is recommended only when you're 100% sure that you have a valid value in your optional.
In your case, it seems that V1.view! causes the crash, and this might be caused by the fact that V1 didn't successfully loaded from the nib.
Swift has made it very easy to work with nullable values. Just don't force unwrap and use optional binding instead.
#Cristik is correct. Instead of force unwrapping the variable, you should check to see if it is instantiated using the "if let" statement:
if let scrollView = self.scrollView {
if let subView = V1.view {
scrollView.addSubview(subView)
}
}

PFUser currentUser returns nil after restarting app

I'm working on a swift iPhone application using Parse for the backend and when I restart the app the currentUser isn't recognized and returns nil redirecting to the login page. Once I sign back in the user stays logged in until I stop the app.
if PFUser.currentUser() == nil {
//return to the login page
} else {
// perform normal operations
}
I'm curious why this is happening since the only place I have PFUser.logOut() is in a logout function which is not on the initial view controller and only called when a button is pressed. Thanks in advance for the help!
EDIT: This problem began occurring this morning. The past 2 weeks I haven't had any issues regarding automatic login with parse. So I don't know what I could have done to cause it. The only code I changed between last night and this morning was trying to pass data from one view controller to a popoverViewController by adding delegates to my VC's but I have since deleted them and am still at a loss.
I ended up downloading the latest Parse SDK and it solved the problem. Eddy from this post PFUser currentUser nil after app update also said reverting to a previous Parse SDK also solved the issue.
I think you should place this code in the AppDelegate into the method applicationDidBecomeActive(), something like the following:
func applicationDidBecomeActive(application: UIApplication)
{
if PFUser.currentUser() == nil{
// show main screen
var storyboard :UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var LoginScreen = storyboard.instantiateViewControllerWithIdentifier("loginShow") as! UIViewController
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(LoginScreen, animated: true, completion: nil)
}
else
{
//show login screen
var storyboard :UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var MainScreenNavigation = storyboard.instantiateViewControllerWithIdentifier("TotalMainViewController") as! UIViewController
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(MainScreenNavigation, animated: false, completion: nil)
}
}

opening a tab bar controller on successful login swift

I am extremely new to swift and storyboards. I have an initial view set which presents the user with login or register options. on the success of my login web service, I am trying to open a tab bar. I am getting into the success of the webservice as I can see the response.
My code for attempting to load the tab bar is as folllows in my initial view controller:
func loadHomeScreen()
{
emailField.text = ""
passwordField.text = ""
self.presentViewController(UIStoryboard.tabbarController()!, animated: true, completion: nil)
}
And at the very bottom of that file, I have the following:
private extension UIStoryboard {
class func mainStoryboard() -> UIStoryboard { return UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()) }
class func tabbarController() -> TabbarController? {
return mainStoryboard().instantiateViewControllerWithIdentifier("TabbarControllerID") as? TabbarController
}
}
And in my storyboard I have given the tabbarcontroller the id above. When I run the app (tested on the simulator for iphone6), I am getting the error 'found nil while unwrapping an Optional value' and this is pointing to the line of code in my loadHome func above (self.presentViewController(UIStoryboard.tabbarController()!, animated: true, completion: nil))
Any help would be appreciated
You could instead instantiate your storyboard like so and the code would look like this under loadHomeScreen():
emailField.text = ""
passwordField.text = ""
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("TabbarControllerID") as! TabbarController
self.presentViewController(vc, animated: true, completion: nil)
You may need to change the bundle to the "mainBundle" as you have in your code, but this should work.
This may not be the optimal solution if your plan is to extend UIStoryboard for instantiating your ViewControllers but I think this might be a little easier/cleaner, depending on how your project is set up.

tableView.reloadData() causes crash in Swift

I read a question asked on Stackoverflow about making a view controller transparent so when it is shown the parent view controller can still be seen behind. I was able to do so:
However now when I click add subject the table view does not add the subject to my tableview like so (this is the view that appears behind the above view when the "+" button is tapped):
but if i exit to my main menu and come back to the table view it displays the list like so (which is what I want when I tap "Add Subject).
I think this is due to tableView.reloadData() being in my ViewWillAppear function.
With this in my mind i added tableViewClass.tableView.reloadData to the "Add Subject" button action in order to reload data as soon as the button is pressed however I get fatal error: found nil while unwrapping optional value and it highlights tableViewClass.tableView.reloadData
I know that the parent view controller (one with the table view) is not killed once the New Subject view controller appears in order to show it behind. This is why "ViewWillAppear" is never called.
Im still a little confused as to why its crashing though... here is my code for my button:
#IBAction func btnAddTask_Click(sender: UIButton){
subMngr.addSubjectMonA(txtSubject.text, time1: txtTime.text, time2: txtTime2.text, col: monAview.ColorValue)
self.view.endEditing(true)
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context: NSManagedObjectContext = appDel.managedObjectContext!
var newCell = NSEntityDescription.insertNewObjectForEntityForName("SubjectsEntity", inManagedObjectContext: context) as NSManagedObject
newCell.setValue(txtTime.text, forKey: "starttime")
newCell.setValue(txtSubject.text , forKey: "title")
newCell.setValue(txtTime2.text , forKey: "endtime")
newCell.setValue(monAview.ColorValue, forKey: "color")
context.save(nil)
txtSubject.text = ""
txtTime.text = ""
txtTime2.text = ""
MondayAClass.TableView.reloadData() // ERROR HERE
dismissViewControllerAnimated(true, completion: nil)
}
Any help would be appreciated, thanks :)
EDIT
Here is my code to present the view controller and make it transparent:
#IBAction func addInfo(sender: AnyObject) {
let story: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let monAadd = story.instantiateViewControllerWithIdentifier("MondayAadd") as MondayAadd
monAadd.view.backgroundColor = UIColor.clearColor()
monAadd.modalPresentationStyle = UIModalPresentationStyle.Custom // If this line is taken out everything works fine
self.presentViewController(monAadd, animated: true, completion: nil)
}
fatal error: found nil while unwrapping optional value
This is Swift's way of saying that you attempted to access a nil value. Ensure that you have an owning relationship between the table view and its view controller, and this shouldn't happen.

Resources