-1

I am trying to get a thumbnail from a video chosen from the image-picker and add the thumbnail into a UIImageView in a separate view-controller however, I am getting the error:

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value in the second view controller

I know what the error means I just don't understand why the thumbnail isn't being passed to the next view controller in the UIImageView

Here is my code for the first view controller.

    @IBAction func upload(_ sender: Any) {
      let pickerController = UIImagePickerController()
      pickerController.delegate = self
      pickerController.mediaTypes = ["public.movie"]
      present(pickerController, animated: true, completion: nil)  
 }
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let videoUrl = info[UIImagePickerControllerMediaURL] as? URL {
        self.vidurl = videoUrl
            func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                if segue.identifier == "toupload" {
                    let uploadvc = segue.destination as! UploadVC
                    uploadvc.videourl = vidurl
                }
            }
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage{
        func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "toupload" {
                let uploadvc = segue.destination as! UploadVC
                uploadvc.previewImage.image = image
            }
        }
    }
    performSegue(withIdentifier: "toupload", sender: nil)
  }
    dismiss(animated: true, completion: nil) 
}

here is the code for the second view-controller

@IBOutlet weak var previewImage: UIImageView!


var videourl: URL?


override func viewDidLoad() {
    super.viewDidLoad()

    previewImage.image = thumbnailImageForFileUrl(videourl!) Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

}

func thumbnailImageForFileUrl(_ fileUrl: URL) -> UIImage? {
    let asset = AVAsset(url: fileUrl)
    let imageGenerator = AVAssetImageGenerator(asset: asset)
    do {
        let thumbnailCGImage = try imageGenerator.copyCGImage(at: CMTimeMake(7, 1), actualTime: nil)
        return UIImage(cgImage: thumbnailCGImage)
    } catch let err {
        print(err)
    }

    return nil
}
  • Justin, did you search it on the internet. There are tons of articles and tutorials explaining how to pass data through Controllers. – GuiDupas Feb 16 '18 at 16:17
  • @GuiDupas yes I have searched the internet and everything said to use the func prepare(for segue: UIStoryboardSegue, sender: Any?) function. – Justin Robinson Feb 16 '18 at 17:17
  • So use it. Create 2 variables inside the class, not inside the method, save the values on them using the method and use `prepare(for segue: UIStoryboardSegue, sender: Any?)` – GuiDupas Feb 16 '18 at 17:20
  • @GuiDupas it worked ! thanks. – Justin Robinson Feb 16 '18 at 21:36

1 Answers1

0

Currently you're nesting prepareForSegue function inside the callback of the picker so remove it and declare it inside the scope of the view controller so when you call performSegue the videoUrl of the class is assigned to the videUrl of the secondVC resulting in non-nil. This should be out and call performSegue

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let videoUrl = info[UIImagePickerControllerMediaURL] as? URL {
    self.vidurl = videoUrl
  }
  else
  {
   }
    performSegue(withIdentifier: "toupload", sender: nil)

 } 

///

   func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "toupload" {
                let uploadvc = segue.destination as! UploadVC
                uploadvc.videourl = vidurl
            }
        }
halfer
  • 19,824
  • 17
  • 99
  • 186
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87