Swift 2 for conditional binding must be an optional type, not 'UIImage'

After updating my xcode to run swift 2, it gives me these two errors that I am trying to solve.

Error 1: Cannot adjust value of type '[String: AnyObject]?' with an index of type 'String'

the code

let image : UIImage = editingInfo[UIImagePickerControllerOriginalImage] as! UIImage 

Error 2: The initializer for conditional binding must be of an optional type, not 'UIImage'

the code

 if let constImage = image (Error2 display here) { let targetWidth = UIScreen.mainScreen().scale * UIScreen.mainScreen().bounds.size.width let resizedImage = constImage.resize(targetWidth) picker.dismissViewControllerAnimated(true, completion: { () -> Void in NetworkManager.sharedInstance.postImage(resizedImage, completionHandler: { (error) -> () in if let constError = error { self.showAlert(constError.localizedDescription) } }) }) } 
+7
swift2
source share
1 answer

The following code ...

 let image : UIImage = editingInfo[UIImagePickerControllerOriginalImage] as! UIImage 

... will fail if there is no UIImagePickerControllerOriginalImage key or if it is not an image.

Where did you get editingInfo ? Because imagePickerController:didFinishPickingImage:editingInfo: not available in Swift. You should use optional func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) .

Your second mistake on the next line ...

 if let constImage = image 

... caused by let image: UIImage = ... . UIImage your image type UIImage , not UIImage? . Thus, this is optional, and you cannot use it in if let constImage = image . Must be UIImage? if you want to use it that way. BTW does not need to use let image: UIImage = ... , let image = ... enough, because the compiler can infer the type of the variable from your statement.

Rewrite it on something like this.

 func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { // throw an error, return from your function, whatever return } // from now you can use `image` safely // it does exist and it not optional let targetWidth = UIScreen.mainScreen().scale * UIScreen.mainScreen().bounds.size.width let resizedImage = image.resize(targetWidth) picker.dismissViewControllerAnimated(true, completion: { () -> Void in NetworkManager.sharedInstance.postImage(resizedImage, completionHandler: { (error) -> () in if let constError = error { self.showAlert(constError.localizedDescription) } }) }) } 

The next part ...

  guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { // throw an error, return from your function, whatever return } 

... doing this...

  • Is there a value in the info dictionary for the UIImagePickerControllerOriginalImage key? if not, else {} is executed,
  • the value is there, can I direct it to UIImage ? if not, else {} is executed,
  • now we have the value from info , successfully entered into UIImage and stored in image , else {} instruction is not executed, and our function continues.

A safe way to get a value from a dictionary of some type if the type of the dictionary is AnyObject for example.

+5
source share

All Articles