zoukankan      html  css  js  c++  java
  • (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

  • 相关阅读:
    LeetCode 230. 二叉搜索树中第K小的元素(Kth Smallest Element in a BST)
    LeetCode 216. 组合总和 III(Combination Sum III)
    LeetCode 179. 最大数(Largest Number)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)
    指针变量、普通变量、内存和地址的全面对比
    MiZ702学习笔记8——让MiZ702变身PC的方法
    你可能不知道的,定义,声明,初始化
    原创zynq文章整理(MiZ702教程+例程)
  • 原文地址:https://www.cnblogs.com/741162830qq/p/4886076.html
Copyright © 2011-2022 走看看