当imagePickerController只返回UIImagePickerControllerReferenceURL时

时间:2015-10-21 20:57:30

标签: ios swift

背景

我有一个应用程序,提示用户选择媒体源:相机 - 或 - 照片库。

媒体捕获完成后(通过“摄像头”选项)或拾取媒体(通过“照片库”选项),我准备所选媒体以上传到服务器(转换为NSData,然后转换为Base64编码的字符串)。这在大多数情况下工作正常。

问题

对于某些视频文件(从照片库中挑选),info字典(传递给imagePickerController)不包含UIImagePickerControllerMediaURL的值。

==>但是,它包含UIImagePickerControllerReferenceURL的值。

来自UIImagePickerControllerReferenceURL的示例网址为:assets-library://asset/asset.MOV?id=39E4A006-F0DB-4EE7-ACB7-624C9B492271&ext=MOV

问题

由于最终目标是转换为NSData对象,请编码为Base64字符串,并上传我应该如何处理此UIImagePickerControllerReferenceURL字符串?我已经尝试使用AssetLibrary获取文件,但我在那里遇到错误。

更概念上讲,导致这种差异的原因是什么?为什么有些视频文件只有一个键而不是另一个?

代码

let optionMenu = UIAlertController(title: nil, message: "Select Source", preferredStyle: .ActionSheet)

        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.mediaTypes = [kUTTypeMovie as String, kUTTypeImage as String]
        imagePicker.videoMaximumDuration = 60.0

        let cameraAction = UIAlertAction(title: "Camera", style: .Default, handler: {
            (alert: UIAlertAction) -> Void in
            if UIImagePickerController.isSourceTypeAvailable(.Camera) {

                imagePicker.sourceType = .Camera
                imagePicker.allowsEditing = false

                self.presentViewController(imagePicker, animated: true, completion: nil)
            }
        })

        let selectAction = UIAlertAction(title: "Photo Library", style: .Default, handler: {
            (alert: UIAlertAction) -> Void in
            if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) {

                imagePicker.sourceType = .PhotoLibrary
                imagePicker.allowsEditing = true

                self.presentViewController(imagePicker, animated: true, completion: nil)
            }
        })

        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {
            (alert: UIAlertAction) -> Void in
            print("Cancelled", terminator: "")
        })

        optionMenu.addAction(cameraAction)
        optionMenu.addAction(selectAction)
        optionMenu.addAction(cancelAction)

        self.presentViewController(optionMenu, animated: true, completion: nil)
}


func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    self.dismissViewControllerAnimated(true, completion: nil)

    let mediaType = info[UIImagePickerControllerMediaType] as! String
    if mediaType == "public.image" {

        let image = info[UIImagePickerControllerOriginalImage] as! UIImage

        // If the image was captured using the camera, save the image to the User's Photo Library
        if picker.sourceType == UIImagePickerControllerSourceType.Camera {
            UIImageWriteToSavedPhotosAlbum(image, self, "image:didFinishSavingWithError:contextInfo:", nil)
        }

        // Correct rotation and convert to Base64
        self.fileToUpload = image.correctlyOrientedImage().toBase64(UIImage.Quality.Medium)
    }
    else if mediaType == "public.movie" {
        if let videoURL = info[UIImagePickerControllerMediaURL] as? NSURL {
            let videoData = NSData(contentsOfURL: videoURL)

            if picker.sourceType == UIImagePickerControllerSourceType.Camera {
                ALAssetsLibrary().writeVideoAtPathToSavedPhotosAlbum(videoURL, completionBlock: nil)
            }

            self.fileToUpload = videoData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
        }
        else if let assetPath = info[UIImagePickerControllerReferenceURL] {
            // What do I do here???
        }
    }

1 个答案:

答案 0 :(得分:0)

这是我最终做的事情,虽然我仍然不理解行为上的差异。

    ....

    else if let assetPath = info[UIImagePickerControllerReferenceURL] as? NSURL {
            let assets = PHAsset.fetchAssetsWithALAssetURLs([assetPath], options: nil)
            if let firstAsset = assets.firstObject as? PHAsset {
                PHCachingImageManager().requestAVAssetForVideo(firstAsset, options: nil, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [NSObject : AnyObject]?) in
                    dispatch_async(dispatch_get_main_queue(), {

                        if let asset = asset as? AVURLAsset {
                            self.fileToUpload = NSData(contentsOfURL: asset.URL)!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
                            // upload now
                        }
                    })
                })
            }
        }