ios - 当 imagePickerController 只返回 UIImagePickerControllerReferenceURL

标签 ios swift

背景

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

一旦媒体捕获完成(通过相机选项)或选择媒体(通过照片库选项),我准备将所选媒体上传到服务器(转换为 NSData,然后转换为 Base64 编码字符串)。这在大多数情况下都很好用。

问题

对于某些 video 文件(从照片库中选取),info 字典(传递给 imagePickerController)不包含以下值UIImagePickerControllerMediaURL

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

来自 UIImagePickerControllerReferenceURL 的示例 URL 是: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???
        }
    }

最佳答案

这是我最终所做的,尽管我仍然不明白行为上的差异。

    ....

    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
                        }
                    })
                })
            }
        }

关于ios - 当 imagePickerController 只返回 UIImagePickerControllerReferenceURL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33269095/

相关文章:

ios - Swift - Xcode 提示额外的参数 - NSDate 初始化

ios - UIView 及其 subview 上的 UITapGestureRecognizer 在 subview 被点击时一起响应

ios - Swift iOS 16 我不能再从键盘上显示 UIViewController,而不关闭它

Swift "get"方法会改变变量的值吗?

ios - 如何在运行时使用哈希值获取指向现有 NSObject 的指针

ios - 不要在 UITableView contentSize 中包含 tableViewFooter?

objective-c - 组合谓词以获得低于常量值的最大值

ios - 页面 curl 过渡在动画结束时挂起的可能原因是什么?

ios - 碰撞后如何阻止分数增加一以上?

ios - UISlider 不占用全宽