terminating with uncaught exception of type NSException

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let alert = SCLAlertView()
        alert.addButton("A",target:self,selector: #selector(FirstViewController.firstButton))
        alert.addButton("B",target:self,selector: #selector(FirstViewController.secondButton))
        self.dismiss(animated: true, completion: {
            alert.showSuccess(kSuccessTitle,subTitle: kSubtitle1)
//            self.present(secondViewController,animated: true,completion: nil)
        })
    }
    @objc func firstButton(info: [UIImagePickerController.InfoKey : Any])
    {
        let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
        let secondViewController = sb.instantiateViewController(withIdentifier: "view2") as! SecondViewController
        secondViewController.infoFromViewOne = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
        secondViewController.flag = 0
        self.present(secondViewController,animated: true,completion: nil)
    }
    @objc func secondButton()
    {
        let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
        let thirdViewcontroller = sb.instantiateViewController(withIdentifier: "SecondViewController") as! ViewController
        self.present(thirdViewcontroller,animated: true,completion: nil)
    }

This is my code,

My desire result is that when I click the first button, the page jump to "SecondViewcontroller" and the image in the SecondViewcontroller's imageView is the photo I just select.


But now , after selecting the photo and click the first button, the app crashes at AppDelegate.swift, with error message:

"libc++abi.dylib: terminating with uncaught exception of type NSException"


What should I do to make it correct?


Thanks in advance.

Answered by OOPer in 356561022

I wrote you need to change the `firstButton` method to:

    @objc func firstButton() { 


But you still keep the method as `firstButton(info: [UIImagePickerController.InfoKey : Any])`, that would never work...

When i click the first button,It does the same, crashed after the line:

self.dismiss(animated: true, completion: { 

The method `magePickerController(_:didFinishPickingMediaWithInfo:)` now is exactly the same as the one in your opening post.

You said you could click the first button, with that exact `magePickerController(_:didFinishPickingMediaWithInfo:)`.


Haven't you mistakenly touched other parts of your code? Please show whole your `FirstViewController` now.

import UIKit
import SCLAlertView

let kSuccessTitle = "Photo is taken"
let kSubtitle1 = "What to do next?"


extension UIColor {
    static func color(_ red: Int, green: Int, blue: Int, alpha: Float) -> UIColor {
        return UIColor(
            red: 1.0 / 255.0 * CGFloat(red),
            green: 1.0 / 255.0 * CGFloat(green),
            blue: 1.0 / 255.0 * CGFloat(blue),
            alpha: CGFloat(alpha))
    }
}

class FirstViewController: UIViewController, CircleMenuDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate{
    let secondViewController = SecondViewController()
    
    @IBAction func to2(_ sender: UIButton) {
        let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
        let view2 = sb.instantiateViewController(withIdentifier: "view2")
        layerTransition(animTye: .cube, subType: .ramdom, curve: .EaseInEaseOut, duration: 0.4, layer: (self.view.window?.layer)!)
        self.present(view2,animated: true,completion: nil)
    }
    //    let secondView = ViewController()
    @IBAction func toView2(_ sender: UIButton) {
        let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
        let secondViewController = sb.instantiateViewController(withIdentifier: "SecondViewController")
        layerTransition(animTye: .cube, subType: .ramdom, curve: .EaseInEaseOut, duration: 0.4, layer: (self.view.window?.layer)!)
        self.present(secondViewController,animated: true,completion: nil)
    }
    var imagePickerController:UIImagePickerController!
    
    enum TransitionAnimType : Int {
        case fade = 0,
        push,
        reveal,
        moveIn,
        cube,
        suckEffect,
        oglFlip,
        rippleEffect,
        pageCurl,
        pageUnCurl,
        cameraIrisHollowOpen,
        cameraIrisHollowClose,
        curlDown,
        curlUp,
        flipFromLeft,
        flipFromRight,
        ramdom
    }
    enum TransitionSubType : Int {
        case top = 0,
        left,
        bottom,
        right,
        ramdom
    }
    
    enum TransitionCurve : Int {
        case Default = 0,
        EaseIn,
        EaseOut,
        EaseInEaseOut,
        Linear,
        Ramdom
    }

    private func animationType(animType: TransitionAnimType) -> String {

        let animTypeArray = ["fade", "push", "reveal", "moveIn", "cube",  "suckEffect", "oglFlip", "rippleEffect", "pageCurl", "pageUnCurl", "cameraIrisHollowOpen", "cameraIrisHollowClose", "curlDown", "curlUp", "flipFromLeft", "flipFromRight", "ramdom"]
        return objectFromDataSource(array: animTypeArray, index: animType.rawValue, isRamdom: (TransitionAnimType.ramdom == animType)) as! String
    }

    private func animationSubType(subType: TransitionSubType) -> String {
        let animSubTypeArray = [CATransitionSubtype.fromTop, CATransitionSubtype.fromLeft, CATransitionSubtype.fromBottom, CATransitionSubtype.fromRight]
        return objectFromDataSource(array: animSubTypeArray, index: subType.rawValue, isRamdom: (TransitionSubType.ramdom == subType)) as! String
    }

    private func animationCurve(curve: TransitionCurve) -> String {
        let animCurveArray = [CAMediaTimingFunctionName.default, CAMediaTimingFunctionName.easeIn, CAMediaTimingFunctionName.easeOut, CAMediaTimingFunctionName.easeInEaseOut, CAMediaTimingFunctionName.linear]
        return objectFromDataSource(array: animCurveArray, index: curve.rawValue, isRamdom: (TransitionCurve.Ramdom == curve)) as! String
    }

    private func objectFromDataSource(array: Array<Any>, index: Int, isRamdom: Bool) -> AnyObject {
        let count = array.count
        let i = isRamdom ? Int(arc4random_uniform(UInt32(count))) : index
        
        return array[i] as AnyObject
    }
    func layerTransition(animTye: TransitionAnimType, subType: TransitionSubType, curve: TransitionCurve, duration: CGFloat, layer: CALayer) {
        let key = "transition"
        if layer.animation(forKey: key) != nil {
            layer.removeAnimation(forKey: key)
        }
        let transition = CATransition()
        

        transition.duration = CFTimeInterval(duration)
        
        transition.type = CATransitionType(rawValue: animationType(animType: animTye))
        

        transition.subtype = CATransitionSubtype(rawValue: animationSubType(subType: subType))
        

        transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName(rawValue: animationCurve(curve: curve)))
        

        transition.isRemovedOnCompletion = true
        
        layer.add(transition, forKey: key)
        
    }
    
    
    //    let colors = [UIColor.redColor(), UIColor.grayColor(), UIColor.greenColor(), UIColor.purpleColor()]
    let items: [(icon: String, color: UIColor)] = [
        ("icon_home", UIColor(red: 0.19, green: 0.57, blue: 1, alpha: 1)),
        ("icon_search", UIColor(red: 0.22, green: 0.74, blue: 0, alpha: 1)),
        ("notifications-btn", UIColor(red: 0.96, green: 0.23, blue: 0.21, alpha: 1)),
        ("settings-btn", UIColor(red: 0.51, green: 0.15, blue: 1, alpha: 1)),
        ("nearby-btn", UIColor(red: 1, green: 0.39, blue: 0, alpha: 1))
    ]
//    @IBInspectable var buttonsCount: Int = 3
//    @IBInspectable var duration: Double = 2 // circle animation duration
//    @IBInspectable var distance: Float = 100 // distance between center button and buttons
    override func viewDidLoad() {
        super.viewDidLoad()
//                        let button = CircleMenu(
//                            frame: CGRect(x: 200, y: 200, width: 50, height: 50),
//                            normalIcon:"icon_menu",
//                            selectedIcon:"icon_close",
//                            buttonsCount: 4,
//                            duration: 4,
//                            distance: 120)
////                        button.backgroundColor = UIColor.lightGrayColor()
//                        button.delegate = self
//                        button.layer.cornerRadius = button.frame.size.width / 2.0
//                        view.addSubview(button)
    }
    override func didReceiveMemoryWarning() {
        
    }
    // MARK: <CircleMenuDelegate>
    
    func circleMenu(_: CircleMenu, willDisplay button: UIButton, atIndex: Int) {
        button.backgroundColor = items[atIndex].color
        
        button.setImage(UIImage(named: items[atIndex].icon), for: .normal)        
        // set highlited image
        let highlightedImage = UIImage(named: items[atIndex].icon)?.withRenderingMode(.alwaysTemplate)
        button.setImage(highlightedImage, for: .highlighted)
        button.tintColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.3)
    }
    
    func circleMenu(_: CircleMenu, buttonWillSelected _: UIButton, atIndex: Int) {
        print("button will selected: \(atIndex)")
    }
    
    func circleMenu(_: CircleMenu, buttonDidSelected _: UIButton, atIndex: Int) {
//        let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
//        let secondView = sb.instantiateViewController(withIdentifier: "secondView")
        print("button did selected: \(atIndex)")
        if(atIndex == 0)
        {
            if(UIImagePickerController.isSourceTypeAvailable(.photoLibrary))
            {
                self.imagePickerController = UIImagePickerController()
                self.imagePickerController.delegate = self
                self.imagePickerController.allowsEditing = true
                self.imagePickerController.sourceType = UIImagePickerController.SourceType.photoLibrary
                layerTransition(animTye: .cameraIrisHollowOpen, subType: .ramdom, curve: .EaseInEaseOut, duration: 0.4, layer: (self.view.window?.layer)!)
                self.present(self.imagePickerController,animated: true,completion: nil)
            }
        }
        if(atIndex == 1)
        {
            let sb1 = UIStoryboard(name:"Main",bundle: Bundle.main)
            let secondView = sb1.instantiateViewController(withIdentifier: "SecondViewController")
            layerTransition(animTye: .cube, subType: .top, curve: .EaseInEaseOut, duration: 0.4, layer: (self.view.window?.layer)!)
             self.present(secondView,animated: true,completion: nil)
        }
        if(atIndex == 2)
        {
            let sb2 = UIStoryboard(name: "Main", bundle: Bundle.main)
            let thirdView = sb2.instantiateViewController(withIdentifier: "view2")
            layerTransition(animTye: .cube, subType: .top, curve: .EaseInEaseOut, duration: 0.4, layer: (self.view.window?.layer)!)
            self.present(thirdView,animated: true,completion: nil)
        }
    }
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        //        self.passingImage = info[.editedImage] as? UIImage
        let alert = SCLAlertView()
        alert.addButton("A",target:self,selector: #selector(FirstViewController.firstButton))
        alert.addButton("B",target:self,selector: #selector(FirstViewController.secondButton))
        self.dismiss(animated: true, completion: {
            alert.showSuccess(kSuccessTitle,subTitle: kSubtitle1)
        })  
    }
    private var passingImage: UIImage?
    @objc func firstButton(info: [UIImagePickerController.InfoKey : Any])
    {
        let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
        let secondViewController = sb.instantiateViewController(withIdentifier: "view2") as! SecondViewController
        secondViewController.flag = 0
        secondViewController.infoFromViewOne = self.passingImage
        self.present(secondViewController,animated: true,completion: nil)
    }
    @objc func secondButton()
    {
        let sb = UIStoryboard(name:"Main",bundle: Bundle.main)
        let thirdViewcontroller = sb.instantiateViewController(withIdentifier: "SecondViewController") as! ViewController
        self.present(thirdViewcontroller,animated: true,completion: nil)
    }
}
Accepted Answer

I wrote you need to change the `firstButton` method to:

    @objc func firstButton() { 


But you still keep the method as `firstButton(info: [UIImagePickerController.InfoKey : Any])`, that would never work...

OMG, I forgot about it.

After putting the code you have provided and removing the '(info: [UIImagePickerController.InfoKey : Any])` , the project is running normally .

I'mSorry that I have been delaying you for so long...

Thanks a lot,you helped me greatly.

OK, hearing that the issue solved, I would sleep well, good night.

terminating with uncaught exception of type NSException
 
 
Q