0
votes

converted app from swift 3 to swift 4.2. my app had a upload your profile image feature that is not working anymore and I am trying to figure out why. For now What I see is that

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo

didFinishPickingMediaWithInfo Is not being called after media was chosen

Here is my views full code:

import UIKit

class CameraMenuViewController: BaseViewController,  UIImagePickerControllerDelegate, UINavigationControllerDelegate {


var UserID:Int = 0


@IBOutlet weak var myImageView: UIImageView!
var callback : ((UIImage) -> ())?

@IBOutlet weak var btn_end: UIButton!
@IBOutlet weak var from_camera: UIBarButtonItem!
@IBOutlet weak var from_gallery: UIBarButtonItem!

@IBAction func btn_end_pressed(_ sender: UIButton) {
    //


    //self.openViewControllerBasedOnIdentifier("Home")

    //let data = UIImagePNGRepresentation(myImageView) as NSData?
    let image = myImageView.image!.pngData() as NSData?

    //if let data = UIImagePNGRepresentation(myImageView) {

        print("callback data")


        let userDetails:Dictionary = (UserDefaults.standard.value(forKey: "myUserDetails") as? [String:Any])!
        let UserID:Int = userDetails["UserID"] as! Int
        print("UserID")
        print(UserID)



        print("is_selfie from callback")


        //save profile image as NewUserID
        UserDefaults.standard.set(image, forKey: String(UserID))
        UserDefaults.standard.synchronize()

        self.view.removeFromSuperview()

    //}



}

@IBAction func btn_closer(_ sender: UIButton) {
    //self.view.removeFromSuperview()
}


@IBAction func photofromLibrary(_ sender: UIBarButtonItem) {
    picker.allowsEditing = false
    picker.sourceType = .photoLibrary
    picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
    picker.modalPresentationStyle = .popover
    present(picker, animated: true, completion: nil)
    picker.popoverPresentationController?.barButtonItem = sender
}



@IBAction func shootPhoto(_ sender: UIBarButtonItem) {
    if UIImagePickerController.isSourceTypeAvailable(.camera) {

        print("photo shoot")

        //UserDefaults.standard.set("selfie", forKey: "is_selfie")
        UserDefaults.standard.set(true, forKey: "is_selfie")
        UserDefaults.standard.synchronize()

        DispatchQueue.main.async {
            self.picker.allowsEditing = false
            self.picker.sourceType = UIImagePickerController.SourceType.camera
            self.picker.cameraCaptureMode = .photo
            self.picker.modalPresentationStyle = .fullScreen
            self.present(self.picker,animated: true,completion: nil)
        }

    } else {
        noCamera()
    }



}


let picker = UIImagePickerController()





override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    picker.delegate = self


    DispatchQueue.global(qos: .userInitiated).async
        {
            self.present(self.picker, animated: true, completion: nil)

        }

    let language = UserDefaults.standard.object(forKey: "myLanguage") as! String

    if(language=="arabic"){
        //from_camera.setTitle("كاميرا",for: .normal)
        //from_gallery.text.setTitle("الصور",for: .normal)
        btn_end.setTitle("إنهاء",for: .normal)
    }





}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}





//MARK: - Delegates
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{



    let chosenImage = info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey.originalImage)] as! UIImage //2
    myImageView.contentMode = .scaleAspectFit //3
    myImageView.image = chosenImage //4


    myImageView.layer.borderWidth = 1
    myImageView.layer.masksToBounds = false
    myImageView.layer.borderColor = UIColor.black.cgColor
    myImageView.layer.cornerRadius = myImageView.frame.height/4
    myImageView.clipsToBounds = true

    callback?(chosenImage)




    dismiss(animated:true, completion: nil)

}

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

func noCamera(){
    let alertVC = UIAlertController(
        title: "No Camera",
        message: "Sorry, this device has no camera",
        preferredStyle: .alert)
    let okAction = UIAlertAction(
        title: "OK",
        style:.default,
        handler: nil)
    alertVC.addAction(okAction)
    present(
        alertVC,
        animated: true,
        completion: nil)
}





}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromUIImagePickerControllerInfoKey(_ input:  UIImagePickerController.InfoKey) -> String {
return input.rawValue
}

Please help me understand why didFinishPickingMediaWithInfo isn't getting called anymore

2

2 Answers

2
votes

It appears as though the function declaration changed between Swift 3 and 4.2. This mustn't have been updated for you by the Swift Migrator Tool. One trick I do when this happens, to check what the correct function declaration is, is to use multiline comment syntax to comment out your current function (didFinishPickingMediaWithInfo in your case). Then you can start typing the function out again, and use Xcode autocomplete to ensure you have it correct. You can then copy the contents of the function you commented out to this new and correct function declaration.

Or - you could just look it up the documentation! According to the documentation on imagePickerController, the function should be declared as:

func imagePickerController(_ picker: UIImagePickerController, 
  didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])

If you replace your function declaration with the above, it should get called again.

1
votes

As Craig said you need to change delegate function declaration and also afterwards you need to update the following:

let chosenImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage

These two changes combined should solve your issue.