Can't Render to ImageView from UIImagePickerController

So I'm developing an app with a friend and I'm trying to wrap my mind around how iOS libraries operate. For whatever reason, my code does not result in the rendering of a user selected photo (from his photo library) to an image view. What am I doing wrong? And, more importantly, how do I debug these sort of problems (I am new to XCode and not sure how debugging works on this platform). Tips and answers are appreciated!


The button function affiliated with this problem is LoadCamRoll and the functions affiliated with what I'm trying to do are imgPicker and imgPickerDidCancel:


import UIKit
import MobileCoreServices
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
  
    @IBOutlet var btnBegin: UIButton!
    @IBOutlet var txtHome: UITextField!
    @IBOutlet var imgLogo: UIImageView!
    @IBOutlet var btnCamSwitch: UIButton!
    @IBOutlet var btnImageSearch: UIButton!
    @IBOutlet var btnBackArrow: UIButton!
    @IBOutlet var btnCamRoll: UIButton!
    @IBOutlet var btnFlash: UIButton!
    @IBOutlet var imgLoaded: UIImageView!
    @IBOutlet var imgLineOut: UIImageView!
  
    var isFlashOn = false
    var isBackCam = false
  
    let imagePicker = UIImagePickerController()
  
    @IBAction func LoadHome(sender: UIButton) {
        btnBegin.removeFromSuperview()
        txtHome.removeFromSuperview()
        imgLogo.hidden = false
        btnFlash.hidden = false
        btnCamSwitch.hidden = false
        btnImageSearch.hidden = false
        btnBackArrow.hidden = false
        btnCamRoll.hidden = false
        imgLineOut.hidden = false
    }
  
    @IBAction func GoBack(sender: UIButton) {
        exit(0)
    }
  
    @IBAction func LoadCamRoll(sender: UIButton) {
        imagePicker.allowsEditing = false
        imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
      
        presentViewController(imagePicker, animated: true, completion: nil)
    }
  
    @IBAction func LoadImgSearch(sender: UIButton) {
        let alertImgSearch = UIAlertController(title: "Load Image Search", message: "Image Search Loaded", preferredStyle: .Alert)
      
        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
        }
      
        alertImgSearch.addAction(cancelAction)
      
        let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
        }
      
        alertImgSearch.addAction(OKAction)
      
        self.presentViewController(alertImgSearch, animated: true){
        }
      
    }
  
    @IBAction func SwitchCam(sender: UIButton) {
        let camString = String(isBackCam)
        let alertBackCam = UIAlertController(title: "Is Back Camera Active?", message: camString, preferredStyle: .Alert)
      
        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
        }
      
        alertBackCam.addAction(cancelAction)
      
        let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
        }
      
        alertBackCam.addAction(OKAction)
      
        self.presentViewController(alertBackCam, animated: true){
        }
      
        isBackCam = !isBackCam
    }
  
    @IBAction func FlashToggle(sender: UIButton) {
      
        if(isFlashOn == false){
            imgLineOut.hidden = false
        }
      
        else if(isFlashOn == true){
            imgLineOut.hidden = true
        }
      
        isFlashOn = !isFlashOn
    }
  
    func imgPicker(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject: AnyObject]){
        let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
            imgLoaded.contentMode = .ScaleAspectFit
            imgLoaded.image = selectedImage
        dismissViewControllerAnimated(true, completion: nil)
    }
  
    func imgPickerDidCancel(picker: UIImagePickerController){
        dismissViewControllerAnimated(true, completion: nil)
    }
  
  
    override func viewDidLoad() {
        super.viewDidLoad()
        imagePicker.delegate = self
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

You misspelled the name of your UIImagePickerControllerDelegate method. If the name of a delegate method isn't spelled correctly, then iOS doesn't recognize the method as a delegate method. A good way to avoid mispelling a delegate method name is to let Xcode autocomplete the method. If Xcode won't autocomplete, then you know you are doing something wrong.


By the way, lines like this:


imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary


can be shortened to:

imagePicker.sourceType =  .PhotoLibrary


Because the sourceType property was declared as type UIImagePickerControllerSourceType, Swift can infer the enumeration type on the right hand side--so all Swift needs to know is the specific enumeration case, e.g. PhotoLibrary. All you have to do is type the leading dot and Xcode will present you with a list of the enumeration's cases to choose from.

And, more importantly, how do I debug these sort of problems?


iOS programming is for intermediate to advanced programmers, and one thing you learn on the way to becoming an intermediate to advanced programmer is how to debug code. Given that, it is still much harder to debug code in Xcode than in other languages. Here are some tips:


1. Print statements.

Add print statements to various methods to print out the values of variables or just identify if a method is even executing. If you had put a print statement in your delegate method, you would have seen that the print statement never executed. Then you would have known that your delegate method wasn't executing, and you could have investigated why.


2. Learn how to use the Xcode debugger.


You can step through your code and try to identify where things aren't working corrrectly. If you had put a break point on the fist line of your UIImagePickerControllerDelegate method in order to examine the variable values and check that an Image actually got assigned to your ImageView, you would have discovered that the breakpoint was never hit.

3. Delete code to isolate the problem.


I copied your code into a new project, and I deleted every line of code in your ViewController that did not pertain to the ImagePicker, then I created a storyboard with only a button and a UIImageView. I still found it difficult to debug your code due to the fact that you had ImagePicker code spread out in a lot of different methods, so code I thought was missing and I identified as the source of the problem was actually elsewhere. You can consolidate your code like this:


class ViewController: UIViewController,
                      UIImagePickerControllerDelegate,
                      UINavigationControllerDelegate
{

    @IBOutlet var imgLoaded: UIImageView!

    @IBAction func LoadCamRoll(sender: UIButton)  {
        let imagePicker = UIImagePickerController()
        imgLoaded.contentMode = .ScaleAspectFit
        imagePicker.sourceType = .PhotoLibrary
        imagePicker.delegate = self
        presentViewController(imagePicker, animated: true, completion: nil)
    }

    func imagePickerController(picker: UIImagePickerController,
                               didFinishPickingMediaWithInfo info: [String: AnyObject])
    {
        let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
        imgLoaded.image = selectedImage
        dismissViewControllerAnimated(true, completion: nil)
    }

    func imgPickerDidCancel(picker: UIImagePickerController){
        dismissViewControllerAnimated(true, completion: nil)
    }

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

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

Would you specify which line specifically had the mispelled UIImagePickerControllerDelegate method? I'm looking around and I don't see it.

Can't Render to ImageView from UIImagePickerController
 
 
Q