Number1 Number1 - 5 months ago 9
iOS Question

Check for nil in data before saving to CoreData

I have this code below that when run I'd like it to check and see if the fields itemName, itemNote, etc are empty and if so display UIAlertController and prevent the user from continuing. The code that I'm attempting to use is under the saveTapped IBAction function. Currently, in runtime it seems to bypass all the checking and goes directly to the "if(item != nil) {" check.

Any insight would be appreciated.

import UIKit
import CoreData

class AddEditViewController: UIViewController, NSFetchedResultsControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

var item : Item? = nil

@IBOutlet weak var itemName: UITextField!
@IBOutlet weak var itemNote: UITextField!
@IBOutlet weak var hoursPlayed: UITextField!
@IBOutlet weak var imageHolder: UIImageView!

let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

override func viewDidLoad() {
super.viewDidLoad()

if item != nil {
itemName.text = item?.name
itemNote.text = item?.note
hoursPlayed.text = item?.hoursPlayed
imageHolder.image = UIImage(data: (item?.image)!)
}
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

@IBAction func AddImage(sender: AnyObject) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
pickerController.allowsEditing = true

self.presentViewController(pickerController, animated: true, completion: nil)
}

@IBAction func addImageFromCamera(sender: AnyObject) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = UIImagePickerControllerSourceType.Camera
pickerController.allowsEditing = true

self.presentViewController(pickerController, animated: true, completion: nil)
}

func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
self.dismissViewControllerAnimated(true, completion: nil)

self.imageHolder.image = image
}

@IBAction func saveTapped(sender: AnyObject) {

var nameMissing = ""

if itemName == nil {
nameMissing = "name"
print("item missing")
}
else if itemNote == nil {
nameMissing = "note"
print("note missing")
}
else if hoursPlayed == nil {
nameMissing = "hours played"
print("hours played missing")
}
else if imageHolder == nil {
nameMissing = "image"
print("image missing")
}

if (itemName == nil || itemNote == nil || hoursPlayed == nil || imageHolder == nil) {
let missingDetailsAlertController = UIAlertController(title: "Alert", message: "Complete field for \(nameMissing).", preferredStyle: UIAlertControllerStyle.Alert)
missingDetailsAlertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(missingDetailsAlertController, animated: true, completion: nil)
return
}

if(item != nil) {
editItem()
} else {
createNewItem()
}
dismissViewController()
}

@IBAction func cancelTapped(sender: AnyObject) {
dismissViewController()
}

func dismissViewController() {
navigationController?.popViewControllerAnimated(true)
}

func createNewItem() {
let entityDescription = NSEntityDescription.entityForName("item", inManagedObjectContext: moc)

let item = Item(entity: entityDescription!, insertIntoManagedObjectContext: moc)

item.name = itemName.text
item.note = itemNote.text
item.hoursPlayed = hoursPlayed.text
item.image = UIImagePNGRepresentation(imageHolder.image!)

do {
try moc.save()
} catch {
print("Create Save Failed.")
return
}
}

func editItem() {
item?.name = itemName.text
item?.note = itemNote.text
item?.hoursPlayed = hoursPlayed.text
item!.image = UIImagePNGRepresentation(imageHolder.image!)

do {
try moc.save()
} catch {
print("Edit Save Failed.")
return
}
}
}

Answer

You should check for text property of your textFields not for nil. Try this:

if let name = itemName.text where name.characters.count > 0 {
   //show your alert
} else if let note = itemNote.text where note.characters.count > 0 {
  //show your alert
} else if let hours = hoursPlayed.text where hours.characters.count > 0 {
  //show your alert
} else if let image = imageHolder.image {
   //show your alert
}

And if you want to access the value without alert then you could try this also for UITextFields:

let name = itemName.text ?? ""
let note = itemNote.text ?? ""
let hours = hoursPlayed.text ?? ""
Comments