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

来源:互联网 时间:1970-01-01

今天在定位一个照片选择奔溃闪退的问题,真机测试所有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 = true4 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: - uiactionsheetDelegatefunc 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.Camerapicker.mediaTypes = [kUTTypeImage]picker.delegate = selfif UIImagePickerController.isCameraDeviceAvailable(UIImagePickerControllerCameraDevice.Front) {picker.cameraDevice = UIImagePickerControllerCameraDevice.Front} else {picker.cameraDevice = UIImagePickerControllerCameraDevice.Rear}delay(0, { () -> () incurrentNav().presentViewController(picker, animated: true, completion: nil)})}} else if buttonIndex == 2 {if (UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.SavedPhotosAlbum)) {let picker = UIImagePickerController()picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrarypicker.mediaTypes = [kUTTypeImage]picker.allowsEditing = falsepicker.delegate = selfdelay(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 = self12 picker.dismissViewControllerAnimated(false, completion: { [unowned self]() -> Void in13 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! NSURL10 let assetLibrary = ALAssetsLibrary()11 assetLibrary.assetForURL(imageUrl, resultBlock: { (asset:ALAsset?) -> Void in12 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 in20 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: RSKImageCropViewController28 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 = self35 picker.dismissViewControllerAnimated(false, completion: { [unowned self]() -> Void in36 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


相关阅读:
Top