Search code examples
swiftrealmnsdata

fatal error: unexpectedly found nil while unwrapping an Optional value when saving NSData to Realm


I want to save an image from an imagePicker with Realm. It works when I choose an picture but not when I don't choose one. I tried to save a standard image when no image is chosen. But I get the error: fatal error: unexpectedly found nil while unwrapping an Optional value Location:

class Location: Object{
dynamic var name = ""
dynamic var locationDescription = ""
dynamic var latitude = 0.0
dynamic var longitude = 0.0
dynamic var created = NSDate ()
dynamic var category: Category!
dynamic var imageData: NSData!
}

Add New Entry Controller:

 //Image Picker
@IBOutlet var imageView: UIImageView!
let imagePicker = UIImagePickerController()
var selectedImage = UIImage()


@IBAction func loadImage(_ sender: AnyObject) {
    imagePicker.allowsEditing = true
    imagePicker.sourceType = .photoLibrary
    imagePicker.mediaTypes =     UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
    present(imagePicker, animated: true, completion: nil)
    }
//MARK: - Delegates Image Picker
func imagePickerController(_ picker: UIImagePickerController,
                           didFinishPickingMediaWithInfo info: [String : Any])
{
    selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage

    imageView.image = selectedImage

    // Dismiss the picker.
    self.dismiss(animated: true, completion: nil)

}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    dismiss(animated: true, completion: nil)
}

func addNewLocation() {
    let realm = try! Realm()
    //convert image to NSData
    let standardData: NSData = UIImagePNGRepresentation(self.imageView.image!)! as NSData
    let selctedImageData = NSData(data: UIImageJPEGRepresentation(selectedImage, 0.9)!)
    let emptyData = NSData()
   // let data = NSData(data: UIImageJPEGRepresentation(selectedImage, 0.9)!)
    var data = NSData()

    if selctedImageData == emptyData{
        data = standardData
    }
    else{
        data = selctedImageData
    }

    try! realm.write {
        let newLocation = Location()


        newLocation.name = self.nameTextField.text!
        newLocation.category = self.selectedCategory
        newLocation.locationDescription = self.descriptionTextField.text
        newLocation.latitude = self.selectedAnnotation.coordinate.latitude
        newLocation.longitude = self.selectedAnnotation.coordinate.longitude
        newLocation.imageData = data


        realm.add(newLocation)
        self.locations = newLocation
    }
}

Edit: I replaced the Category Model with an string which is generated from an query.

class Location: Object{
...
dynamic var category = ""
dynamic var imageData: NSData!

}

Solution

  • I solved the problem like this:

    class Location: Object{
    dynamic var name = ""
    dynamic var locationDescription = ""
    dynamic var latitude = 0.0
    dynamic var longitude = 0.0
    dynamic var category = ""
    dynamic var imageData: NSData? = nil
    
    }
    
    
     //Image Picker
    @IBOutlet var imageView: UIImageView!
    let imagePicker = UIImagePickerController()
    var selectedImage = UIImage()
    
    
    @IBAction func loadImage(_ sender: AnyObject) {
        imagePicker.allowsEditing = true
        imagePicker.sourceType = .photoLibrary
        imagePicker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
        present(imagePicker, animated: true, completion: nil)
    }
        //MARK: - Delegates Image Picker
    func imagePickerController(_ picker: UIImagePickerController,
                               didFinishPickingMediaWithInfo info: [String : Any])
    {
        selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
    
        imageView.image = selectedImage
    
        // Dismiss the picker.
        self.dismiss(animated: true, completion: nil)
    
    }
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion: nil)
    }
    
    func addNewLocation() {
    
    
        let imageData: NSData = UIImagePNGRepresentation(self.imageView.image!)! as NSData
    
    
    
    
    
    
        let realm = try! Realm()
    
        try! realm.write {
            let newLocation = Location()
    
            newLocation.name = self.nameTextField.text!
            newLocation.category = self.selectedCategory
            newLocation.locationDescription = self.descriptionTextField.text
            newLocation.latitude = self.selectedAnnotation.coordinate.latitude
            newLocation.longitude = self.selectedAnnotation.coordinate.longitude
    
    
    
            newLocation.imageData = imageData
    
            realm.add(newLocation)
            self.locations = newLocation
        }
    }