(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

posted @ 2015-10-16 18:42  Qingyun_Qearl  阅读(7771)  评论(0编辑  收藏  举报