terminating with uncaught exception of type NSException in Swift - swift

I am pretty new to swift and was just playing around with the following tutorial to learn Core Data Basics.
CoreData Tutorial
I've tried to narrow down where the exception is being thrown using breaks. I believe it is when I am trying to pass data through a view controller.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Update" {
// var selectedItem: NSManagedObject = myList[self.tableView.indexp] as NSManagedObject
let IVC: CreateRiderViewController = (segue.destinationViewController as? CreateRiderViewController)!
var indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow()!
var selectedItem: NSManagedObject = myList[indexPath.row] as! NSManagedObject
IVC.firstName = (selectedItem.valueForKey("firstName") as?String)!
IVC.lastName = (selectedItem.valueForKey("lastName") as! String?)!
IVC.phoneNumber = (selectedItem.valueForKey("phoneNumber") as! String?)!
IVC.eMail = (selectedItem.valueForKey("eMail") as! String?)!
IVC.exitingItem = selectedItem
}
}
The view controller I'm attempting to pass this data too looks like this.
class CreateRiderViewController: UIViewController {
#IBOutlet weak var firstNameField: UITextField!
#IBOutlet weak var lastNameField: UITextField!
#IBOutlet weak var phoneNumberField: UITextField!
#IBOutlet weak var eMailField: UITextField!
var exitingItem: NSManagedObject!
var firstName: String = ""
var lastName: String = " "
var phoneNumber: String = " "
var eMail: String = " "
override func viewDidLoad() {
super.viewDidLoad()
if (exitingItem != nil) {
firstNameField.text = firstName
lastNameField.text = lastName
phoneNumberField.text = phoneNumber
eMailField.text = eMail
}
// Do any additional setup after loading the view.
}
It should set the text fields text to the row selected from my first view controller. However when i select a row the program seems to crash at the point it is transitioning view controllers.
The error I am getting is
2015-06-09 15:53:51.193 ARRR[37189:4601772] -[UITextInputTraits length]: unrecognized selector sent to instance 0x7fc129f60800
2015-06-09 15:53:51.198 ARRR[37189:4601772] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[UITextInputTraits length]: unrecognized selector sent to instance 0x7fc129f60800'
I believe I am unwrapping something at the wrong time but can not figure it out.
I'm also trying to become better at sharing information to get help trouble shooting and would appreciate feedback on how I can explain my problems more clearly and know if I'm including the right pieces of code / error messages to find the problem.

Check that your UITextField is connected to your ViewController.
ctrl-click on all UITextFields in the storyboard and check for broken links (you might have created an outlet in the code but changed its name). Also check that all outlets in the ViewController are connected (a circle appears to the left of the initialisation line, if it's filled it's connected, if it's an empty circle there's a broken link)
Screenshot

Related

How to retrieve the value of switch and pass into Object?

I am trying to get the value of a switch and pass it to an object in a view controller.
Below is the code of my view controller. I have created a label, switch outlet, and switch action.
#IBOutlet weak var firstTimeConducting: UILabel!
#IBOutlet weak var firstTime_Conduct: UISwitch!
#IBAction func firstTimeConductSwitchTap(_ sender: Any) {
firstTimeConductTapped()
}
override func viewDidLoad() {
super.viewDidLoad()
firstTimeConductTapped()
}
func firstTimeConductTapped() {
if firstTime_Conduct.isOn {
value = "Yes"
} else {
value = "No"
}
}
I have debugged it and it enters and gets the value as "yes" when I click on the switch from off to on state in simulator.
Then after returning to function firstTimeConductSwitchTap(), it crashes saying the following error
"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[app.RequestFormViewController first_TimeConduct:]: unrecognized selector sent to instance 0x7fb900421fc0'
I am just retrieving the value of "value" variable and passing it to object to display.
Can you suggest whether I am following the correct procedure and why I get this error?
The error is pretty clear:
In Interface Builder there is a dead connection to a selector first_TimeConduct. Most likely you renamed the action method.
Search for first_TimeConduct with ⇧⌘F and delete the connection.

change to another screen after login is successful

The use case of the app I am developing is I will have login view at the initial. When user logs in with valid credentials, the user should see another view saying welcome user. I am totally beginner and I don't know much more about xcode. I see the screen navigation from storyboard but I have already done many things in xib.
Here is what I have done
SafariExtensionViewController.swift
import SafariServices
class SafariExtensionViewController: SFSafariExtensionViewController {
#IBOutlet weak var passwordMessage: NSTextField!
#IBOutlet weak var emailMessage: NSTextField!
#IBOutlet weak var message: NSTextField!
#IBOutlet weak var email: NSTextField!
#IBOutlet weak var password: NSSecureTextField!
static let shared = SafariExtensionViewController()
override func viewDidLoad() {
self.preferredContentSize = NSSize(width: 300, height: 250)
message.stringValue = ""
emailMessage.stringValue = ""
passwordMessage.stringValue = ""
}
#IBAction func userLogin(_ sender: Any) {
let providedEmailAddress = email.stringValue
let providedPassword = password.stringValue
let isEmailAddressValid = isValidEmailAddress(emailAddressString: providedEmailAddress)
self.message.stringValue = ""
emailMessage.stringValue = ""
passwordMessage.stringValue = ""
if isEmailAddressValid && providedPassword.count > 0 {
// api call is done here
// when success should show another screen
} else {
emailMessage.textColor = NSColor.red
emailMessage.stringValue = "Invalid Email"
}
}
}
here is the screenshot of xib.
Technology used
swift 4
xcode 9
not IOS its mainly for app extension
UPDATE
I am not using storyboard and also it's not IOS. I am using xib and from macos project I am trying to develop app extension which will be shown in browser as an extension.
A lot of time left from question posted, but it can be helpful for others as me (I'm porting safari legacy extension to safari app extension) and find the way with use of NSTabView with tabless style:
The use is:
Ensure to add NSObject in your storyboard from the Library:
And connect with the tabview from Outlet:
I'm rather newbie in Cocoa and Swift and if anyone knows more beautiful solution for routing, please share it with others!

CoreData: prepare for segue NSManagedObject issue in Swift 3

I am a beginner student in Swift 3 and I am currently studying CoreData. I am trying to do an App where I have a first controller that is a list view (tableviewcontroller) where I can see some students. Inside each cell, I have an image (UIImage) and 4 labels (Strings: name, preceptor, note and date) who fetch data from an Array that keeps the information from the entity "AlunosLista", who has one attribute for each item (image is binary data). I can add these information through another view controller (AddDataVC.swift) and list them perfectly. The app until here is fine. What i cannot do, and i have been trying a lot of things, many things, is to send the data from the row selected (clicked) to another viewcontroller for the detailed view (DetailsVC.swift). When i was using a simple Array, without CoreData, worked fine. But now i cannot do it. Now parts of the code:
File (1): TableviewController
class TabelaListagem: UITableViewController {....
import CoreData
import UIKit
var alunos: [NSManagedObject?] = []
var gerenciadorDeDados: NSManagedObjectContext? = nil
override func viewDidLoad() {
super.viewDidLoad()
//CORE DATA
let AppleObject = UIApplication.shared.delegate as! AppDelegate
gerenciadorDeDados = AppleObject.persistentContainer.viewContext
LoadFetch()
}
(.......)
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let path = alunos[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "celulaReuso", for: indexPath) as! ListagemCelulas
cell.lblAluno.text = path?.value(forKey: "nome") as? String
cell.lblPreceptor.text = path?.value(forKey: "preceptor") as? String
cell.lblData.text = path?.value(forKey: "dataHoje") as? String
cell.lblNotaAluno.text = path?.value(forKey: "nota") as? String
let caminhodaImagem = path?.value(forKey: "fotoAluno")
cell.imgAluno.image = UIImage(data: (caminhodaImagem as? NSData) as! Data)
return cell
}
Here should place the prepare(for segue), that I have tried many ways. This was the last one, who didn't worked too. "Build succeeded", but crashed.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueAluno" {
if let pathC = tableView.indexPathForSelectedRow{
let VCDestino = segue.destination as? DescriAluno
let objeto = FecthResultado?.object(at: pathC)
VCDestino?.alunoD = objeto as! NSManagedObject?
}
}
}
File (2) DetailViewController
import UIKit
import CoreData
class DescriAluno: UIViewController {
#IBOutlet weak var imgFotoAluno: UIImageView!
#IBOutlet weak var nomeAluno: UILabel
#IBOutlet weak var txtPreceptor: UILabel!
#IBOutlet weak var txtNotaAluno: UILabel!
#IBOutlet weak var txtDataHoje: UILabel!
var gerenciadorDeDados: NSManagedObjectContext!
var alunoD: NSManagedObject?
override func viewDidLoad() {
super.viewDidLoad()
//CORE DATA
let AppleObject = UIApplication.shared.delegate as! AppDelegate
gerenciadorDeDados = AppleObject.persistentContainer.viewContext
imgFotoAluno.image = alunoD?.value(forKey: "fotoAluno")
nomeAluno.text = alunoD?.value(forKey: "nome")
txtPreceptor.text = alunoD?.value(forKey: "preceptor")
txtNotaAluno.text = alunoD?.value(forKey: "nota")
txtDataHoje.text = alunoD?.value(forKey: "dataHoje")
}
Error message after crash:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: 'executeFetchRequest:error:
is not a valid NSFetchRequest.'
I really don't know how to proceed. I have tried so many things, some of them told about NSFetchedResults, but i could write or understand them. If any one could help here, I appreciate. Thank you.
This is the Fetch request (func):
Ok. This is my fetch request:
func LoadFecth() {
let ordenacaoAZ = NSSortDescriptor(key: "nome", ascending: true)
let ordenacaoAZPrecep = NSSortDescriptor(key: "preceptor", ascending: true)
let recupoerardados = NSFetchRequest<NSFetchRequestResult>(entityName: "AlunosLista")
recupoerardados.sortDescriptors = [ordenacaoAZPrecep, ordenacaoAZ]
do{
let recupera = try gerenciadorDeDados?.fetch(recupoerardados)
self.alunos = recupera as! [NSManagedObject]
self.tableView.reloadData()
}catch let erro as NSError{
print("Erro ao carregar: \(erro.description)")
}
}
Your core data life will get easier in every way if you use NSManagedObject subclasses for your entities. This allows you to use convenience accessors to get typed fetch requests and to skip all this value(forKey: stuff and use properties.
The error is that your fetch request is not valid.
You may have mistyped the entity name ("AlunosLista").
It may be getting upset because the type of the fetch request, without a specific NSManagedObject subclass, is actually NSFetchRequest<NSManagedObject>.
The best thing to do is enter a subclass for the entity in the model editor, generate the subclass files, then use this:
let recupoerardados: NSFetchRequest<AlunosLista> = AlunosLista.fetchRequest()

Saving Labels in NSUserDefault in Swift

So in the app I'm creating I have a settings view controller where users can type their information in the textfields and then when they click the done button it loads all that information to labels on the home view controller . How can I save the data in the home view controller with NSUserDefault? I'm using two view controllers.
Settings View Controller
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
let DestViewController = segue.destinationViewController as! home
DestViewController.NameText = NameTextField.text!
DestViewController.positionText = positionTextField.text!
DestViewController.divisionText = divisionTextField.text!
DestViewController.routeText = routeTextField.text!
DestViewController.routeText = routeTextField.text!
DestViewController._picture = _picture.image!
NSUserDefaults.standardUserDefaults().setValue(NameTextField.text!, forKey: "name")
NSUserDefaults.standardUserDefaults().setValue(positionTextField.text!, forKey: "position")
NSUserDefaults.standardUserDefaults().setValue(divisionTextField.text!, forKey: "division")
NSUserDefaults.standardUserDefaults().setValue(routeTextField.text!, forKey: "route")
NSUserDefaults.standardUserDefaults().setValue(_picture, forKey: "ImageKey")
}
Home View Controller
class home: UIViewController, UITextFieldDelegate {
#IBOutlet weak var Name: UILabel!
#IBOutlet weak var position: UILabel!
#IBOutlet weak var division: UILabel!
#IBOutlet weak var route: UILabel!
var contacts = MyContacts()
var NameText = String()
var positionText = String()
var divisionText = String()
var routeText = String()
var _picture: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
Name!.text = NSUserDefaults.standardUserDefaults().stringForKey("name")
position!.text = NSUserDefaults.standardUserDefaults().stringForKey("position")
division!.text = NSUserDefaults.standardUserDefaults().stringForKey("division")
route!.text = NSUserDefaults.standardUserDefaults().stringForKey("route")
Profile!.image = _picture
}
All of these codes work perfect, I'm just wondering if you could help me save the labels in NSUserDefault so every time the app is loaded all the information is still there. I've done a lot of research on this topic, but can find a solution for my problem. Any help would be much appreciated.
Just use basic syntax:
NSUserDefaults.standardUserDefaults().setValue(value, forKey:key)
Save example:-
NSUserDefaults.standardUserDefaults().setValue(positionTextField.text!, forKey: "position")
Retrieve example:-
position!.text=NSUserDefaults.standardUserDefaults().stringForKey("position")
Note: remember the key must be unique.
I have created following 2 functions which does Saving & Retrieving of Data using NSUserDefault. Refer it and use accordingly.
func saveDataInUserDefault()
{
// *** init NSUserDefaults ***
let userDefaults = NSUserDefaults()
// *** Init a UIImage, you can use your UIImage instead ***
let img = UIImage.init(imageLiteral: "image")
// *** set values in UserDefault as well image ***
userDefaults.setObject("value of name textfield", forKey: "name")
userDefaults.setObject("value of position textfield", forKey: "position")
userDefaults.setObject("value of division textfield", forKey: "division")
userDefaults.setObject("value of route textfield", forKey: "route")
// *** convert image to NSData and store it ***
userDefaults.setObject(UIImageJPEGRepresentation(img, 1.0), forKey: "image")
// *** save all the changes to NSUserDefaults ***
userDefaults.synchronize()
}
func getDataFromUserDefaults()
{
// *** Now lets access all the stored data from user default ***
// *** init NSUserDefaults ***
let userDefaults = NSUserDefaults()
// *** to get normal objects use following ***
print(userDefaults.objectForKey("name"))
// *** to load image use following ***
let img = UIImage(data:userDefaults.objectForKey("image") as! NSData)
}

Why am I getting a nil for a UITableViewCell's UILabel?

Why am I getting a 'nil' error/UILabel during my second pass thru the table cell listing iteration?
1) Inside cell
2) Inside cell
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb) po cell?.contentView.viewWithTag(TitleLabelTag)
nil
Here I link the elements in the code; and register the cell:
class DiaryTableViewCell: UITableViewCell {
#IBOutlet weak var TitleLabel: UILabel!
#IBOutlet weak var SubTitleLabel: UILabel!
#IBOutlet weak var leftImageView: UIImageView!
#IBOutlet weak var rightImageView: UIImageView!
}
class DiaryTableViewController: UITableViewController {
let kCellIdentifier = "DiaryCell"
var cellNib:UINib?
var diaryCell:DiaryTableViewCell?
var objects = NSMutableArray() //...global var.
override func viewDidLoad() {
self.title = "My Diary"
cellNib = UINib(nibName: "TableViewCells", bundle: nil)
tableView.registerClass(DiaryTableViewCell.self, forCellReuseIdentifier: kCellIdentifier)
}
...
Yet I'm getting the runtime error here:
Here's what I get in the console:
1) Inside cell
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb) po cell!.TitleLabel
nil
What's missing here?
It's a pretty bad idea to select a view with a tag. It's a much better idea to subclass your UITableViewCell and give it a property to access the elements.
If you are creating static cells and loading you need to create an IBoutlet for them in your .h correctly.
Moreover remove line
tableView.registerClass(...) statement from your code. Look at this link might help and is very similar except its for collectionview. -
Why is UICollectionViewCell's outlet nil?
1) I moved the cell registration to the viewDidLoad().
2) I forgot to place the '?' after the TitleLabel & SubTitleLabel; to notify the compiler that these labels could be nil.
I don't see the altered cell yet (empty rows); but I'm not getting runtime errors.
Unfortunately I merely cured the symptom; not the cause. I'm still getting nil UILabels.
...working on revision and cleaner code.