• (Swift) UIImagePickerController照片选择器UIImagePickerControllerReferenceURL的问题


    今天在定位一个照片选择奔溃闪退的问题,真机测试所有iPhone运行正常,ipad测试中使用ipad Air ios8的时候总算问题复现了。下面我总结一下自己测试一天才测试出来的bug。

    现象:点击个人主页头像,进行照片选择,点击照片,应用程序闪退。

    iOS 获取图片有三种方法:

    1. 直接调用摄像头拍照

    2. 从相册中选择

    3. 从图库中选择

          UIImagePickerControllerSourceTypePhotoLibrary:表示显示所有的照片

          UIImagePickerControllerSourceTypeCamera:表示从摄像头选取照片

          UIImagePickerControllerSourceTypeSavedPhotosAlbum:表示仅仅从相册中选取照片。

      allowEditing和allowsImageEditing  设置为YES,表示 允许用户编辑图片,否则,不允许用户编辑。

    代码如下:

    1     @IBAction func onCoverClick(sender: AnyObject) {
    2         if (UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.SavedPhotosAlbum)) {
    3             self.coverChanging = true
    4 
    5             let actionSheet = UIActionSheet( title: Localized.PHOTO_CHOSE_SOURCE, delegate: self, cancelButtonTitle:Localized.DIALOG_BUTTON_CANCEL , destructiveButtonTitle: nil, otherButtonTitles: Localized.PHOTO_FROM_CAMERA, Localized.PHOTO_FROM_PHOTO )
    6             actionSheet.showInView(self.view)
    7         }
    8     }
        //MARK: - uiactionsheetDelegate
        func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int)
        {
            Flurry.logEvent("Clicked change user avatar")
            if buttonIndex == 1 {
                if(UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)) {
                    let picker = UIImagePickerController()
                    picker.sourceType = UIImagePickerControllerSourceType.Camera
                    picker.mediaTypes = [kUTTypeImage]
                    picker.delegate = self
                    if UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDevice.Front) {
                        picker.cameraDevice = UIImagePickerControllerCameraDevice.Front
                    } else {
                        picker.cameraDevice = UIImagePickerControllerCameraDevice.Rear
                    }
                    delay(0, { () -> () in
                    currentNav().presentViewController(picker, animated: true, completion: nil)
                    })
                }
            } else if buttonIndex == 2 {
                if (UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.SavedPhotosAlbum)) {
                    let picker = UIImagePickerController()
                    picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
                    picker.mediaTypes = [kUTTypeImage]
                    picker.allowsEditing = false
                    picker.delegate = self
                    delay(0, { () -> () in
                     currentNav().presentViewController(picker, animated: true, completion: nil)
                    })
                }
            }
    
        }

    下面是有bug的代码:如下,直接获取info字典中UIImagePickerControllerOriginalImage 的image,然后使用框架赋值操作

     1     func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
     2         MBProgressHUD.showHUDAddedTo(self.view, animated: true, needMask: false)
     3         let img = info[UIImagePickerControllerOriginalImage] as! UIImage
     4         var cropCtrl: RSKImageCropViewController
     5         if self.coverChanging {
     6             let width = min(UIScreen.mainScreen().bounds.size.width , UIScreen.mainScreen().bounds.size.height)
     7             cropCtrl = RSKImageCropViewController(image: img, cropMode: RSKImageCropMode.Custom, cropSize: CGSizeMake(width, width * 10 / 16))
     8         } else {
     9             cropCtrl = RSKImageCropViewController(image: img, cropMode: RSKImageCropMode.Circle, cropSize: CGSizeMake(512, 512))
    10         }
    11         cropCtrl.delegate = self
    12         picker.dismissViewControllerAnimated(false, completion: { [unowned self]() -> Void in
    13             self.presentViewController(cropCtrl, animated: false, completion: nil)
    14             })
    15     }

    代码在iPhone下测试没有问题。在ipad air上测试直接崩溃,我打印出info信息如下:

    ["UIImagePickerControllerReferenceURL": assets-library://asset/asset.JPG?id=7136137D-8D6C-409D-A4A4-7520924F4AD4&ext=JPG, "UIImagePickerControllerMediaType": public.image]

    下面来看看正常的打印info信息的输出:

    ["UIImagePickerControllerOriginalImage": <UIImage: 0x188a1010> size {480, 640} orientation 3 scale 1.000000, "UIImagePickerControllerMediaMetadata": {

        DPIHeight = 72;

        DPIWidth = 72;

        Orientation = 6;

        "{Exif}" =     {

            ApertureValue = "2.526068811667588";

            BrightnessValue = "4.991759637258034";

            ColorSpace = 1;

            DateTimeDigitized = "2015:10:15 15:32:42";

            DateTimeOriginal = "2015:10:15 15:32:42";

            ExposureBiasValue = 0;

            ExposureMode = 0;

            ExposureProgram = 2;

            ExposureTime = "0.007518796992481203";

            FNumber = "2.4";

            Flash = 32;

            FocalLenIn35mmFilm = 35;

            FocalLength = "1.85";

            ISOSpeedRatings =         (

                125

            );

            LensMake = Apple;

            LensModel = "iPad 2 front camera 1.85mm f/2.4";

            LensSpecification =         (

                "1.85",

                "1.85",

                "2.4",

                "2.4"

            );

            MeteringMode = 5;

            PixelXDimension = 640;

            PixelYDimension = 480;

            SceneType = 1;

            SensingMethod = 2;

            ShutterSpeedValue = "7.059855806488952";

            SubsecTimeDigitized = 674;

            SubsecTimeOriginal = 674;

            WhiteBalance = 0;

        };

        "{MakerApple}" =     {

            1 = 2;

            3 =         {

                epoch = 0;

                flags = 1;

                timescale = 1000000000;

                value = 9309095690750;

            };

            4 = 1;

            5 = 200;

            6 = 224;

            7 = 1;

            8 =         (

                "0.006874616",

                "-0.2249842",

                "-0.9852664"

            );

        };

        "{TIFF}" =     {

            DateTime = "2015:10:15 15:32:42";

            Make = Apple;

            Model = "iPad 2";

            Software = "8.3";

            XResolution = 72;

            YResolution = 72;

        };

    }, "UIImagePickerControllerMediaType": public.image]

    从这里可以看出来,直接取值是有很大问题的。

    所以我进行了如下操作,判断取值,如果最后imge仍没有值,弹框提示用户重新选择照片。代码如下:

    需要导入:

    import AssetsLibrary

     1    // MARK : - imageCrop
     2     func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
     3         MBProgressHUD.showHUDAddedTo(self.view, animated: true, needMask: false)
     4         var img = UIImage()
     5         if  info[UIImagePickerControllerOriginalImage] != nil {
     6             img = info[UIImagePickerControllerOriginalImage] as! UIImage
     7             self.showRSkImageCropController(picker, img: img)
     8         } else if info[UIImagePickerControllerReferenceURL] != nil {
     9             let imageUrl = info[UIImagePickerControllerReferenceURL] as! NSURL
    10             let assetLibrary = ALAssetsLibrary()
    11             assetLibrary.assetForURL(imageUrl, resultBlock: { (asset:ALAsset?) -> Void in
    12                 if let imageRef = asset?.defaultRepresentation().fullScreenImage() {
    13                     img = UIImage(CGImage: imageRef as! CGImageRef)
    14                     self.showRSkImageCropController(picker, img: img)
    15                 } else {
    16                     let imageActionSheet =  UIActionSheet(title:Localized.PHOTO_CHOSE_ERROR, delegate: nil, cancelButtonTitle:Localized.DIALOG_BUTTON_CANCEL, destructiveButtonTitle:Localized.DIALOG_BUTTON_OK)
    17                     imageActionSheet.showInView(picker.view)
    18                 }
    19                 }) { (error:NSError?) -> Void in
    20                     let imageActionSheet =  UIActionSheet(title:Localized.PHOTO_CHOSE_ERROR, delegate: nil, cancelButtonTitle:Localized.DIALOG_BUTTON_CANCEL, destructiveButtonTitle:Localized.DIALOG_BUTTON_OK)
    21                     imageActionSheet.showInView(picker.view)
    22             }
    23         }
    24     }
    25 
    26     func showRSkImageCropController(picker:UIImagePickerController,img:UIImage) {
    27         var cropCtrl: RSKImageCropViewController
    28         if self.coverChanging {
    29             let width = min(UIScreen.mainScreen().bounds.size.width , UIScreen.mainScreen().bounds.size.height)
    30             cropCtrl = RSKImageCropViewController(image: img, cropMode: RSKImageCropMode.Custom, cropSize: CGSizeMake(width, width * 10 / 16))
    31         } else {
    32             cropCtrl = RSKImageCropViewController(image: img, cropMode: RSKImageCropMode.Circle, cropSize: CGSizeMake(512, 512))
    33         }
    34         cropCtrl.delegate = self
    35         picker.dismissViewControllerAnimated(false, completion: { [unowned self]() -> Void in
    36             self.presentViewController(cropCtrl, animated: false, completion: nil)
    37             })
    38     }

    参考的链接如下:

    链接1:http://www.bubuko.com/infodetail-846042.html

    链接2:http://www.cnblogs.com/liangxing/archive/2013/01/05/2846136.html

    链接3:http://blog.csdn.net/mideveloper/article/details/12997453

  • 相关阅读:
    第五周作业
    画图实例:一个计算机商店的基于Wed的订单处理系统的DFD图和ER图
    为什么要进行需求分析?通常对软件系统有哪些需求?
    面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里
    几大开发模式的区别与联系
    说说我的困惑
    Python单元测试——深入理解unittest
    Devexpress 自定义下拉列表
    Devexpress TextEdit设置文本只能输入数字
    jetbain软件授权码
  • 原文地址:https://www.cnblogs.com/741162830qq/p/4886076.html
Copyright © 2020-2023  润新知