didFinishPickingMediaWithInfo在iOS 13中返回不同的URL

Kun*_*hah 5 uiimagepickercontroller ios swift ios13

- (void)videoPickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info

在iOS 13和其他iOS中返回不同的URL。

知道为什么会这样吗?

iOS 13:

file:///private/var/mobile/Containers/Data/PluginKitPlugin/0849234B-837C-43ED-BEDD-DE4F79E7CE96/tmp/trim.B8AB021D-F4B6-4E50-A93C-8B7F7FB40A1C.MOV
Run Code Online (Sandbox Code Playgroud)

<iOS 13:

file:///private/var/mobile/Containers/Data/Application/5AE52A95-6A2F-49A5-8210-D70E022E9A05/tmp/5A8D81B5-FC42-4228-9514-CD998A4E7FA9.MOV
Run Code Online (Sandbox Code Playgroud)

由于我没有该PluginKitPlugin文件夹的权限,因此这导致我出现错误。

在这两种情况下,我都使用来选择视频imagePicker

小智 13

我为此挣扎了几个晚上,终于解决了这个问题。

此处用例的不同之处之一是我将视频上传到 AWS S3。这是通过后台线程中的 S3 传输实用程序发生的。经过大量的试验和调试,这就是我所确定的。

变化在于,在 iOS 13 中,图像选取器控制器 didFinishPickingMediaWithInfo 方法在 info[ .mediaURL ] 参数中返回的mediaURL指向“ PluginKitsPlugin ”目录下的临时文件夹。我们的应用似乎很长时间无法访问此位置。

示例:file:///private/var/mobile/Containers/Data/ PluginKitPlugin /0849234B-837C-43ED-BEDD-DE4F79E7CE96/ tmp /trim.B8AB021D-F4B6-4E50-A93C-8B7F7FB40A1

出于某种原因(也许其他人知道)只能暂时访问该 URL。这里的一些理论表明,关闭图像选择器控制器将取消分配 URL,从而使其无效。

有了这个理论,我试图解决这两种不同的方法:

  1. 在上传发生之前不要关闭图像选择器。这没有用。S3 传输实用程序的后台进程仍然因“找不到文件”错误而悄然死去。
  2. 传递对信息字典的引用,并在尽可能靠近上传点的地方使用它。我正在上传到 AWS S3,因此当 S3 在后台上传时,信息字典的取消引用可能仍在发生。

最终解决问题的是将 info[.mediaURL] 复制到我的应用程序的临时文件夹中的另一个可用位置。

这是我用来将 info[ .mediaURL ]复制到我的应用程序的临时文件夹的代码。

     This function will copy a video file to a temporary location so that it remains accessbile for further handling such as an upload to S3.
     - Parameter url: This is the url of the media item.
     - Returns: Return a new URL for the local copy of the vidoe file.
     */
    func createTemporaryURLforVideoFile(url: NSURL) -> NSURL {
        /// Create the temporary directory.
        let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
        /// create a temporary file for us to copy the video to.
        let temporaryFileURL = temporaryDirectoryURL.appendingPathComponent(url.lastPathComponent ?? "")
        /// Attempt the copy.
        do {
            try FileManager().copyItem(at: url.absoluteURL!, to: temporaryFileURL)
        } catch {
            print("There was an error copying the video file to the temporary location.")
        }

        return temporaryFileURL as NSURL
    }
Run Code Online (Sandbox Code Playgroud)

此代码将文件复制到如下临时目录中,您的应用程序在其生命周期中可以访问该目录:file:///private/var/mobile/Containers/Data/ Application/5AE52A95-6A2F-49A5-8210-D70E022E9A05/tmp /5A8D81B5-FC42-4228-9514-CD998A4E7FA9.MOV

您会注意到选择要上传的图像 (info[ .imageURL ]) 将返回同一目录中的文件。上传图片之前没有问题。

这样,S3 传输实用程序就能够在后台线程中访问该文件并完成将视频上传到 S3。


rsi*_*que 7

该问题可能与 url 的生命周期有关,该生命周期与NSDictionary<UIImagePickerControllerInfoKey,id> *)info对象的生命周期有关。如果对象被释放,则 url 无效。因此,您可以保留对对象的引用或将媒体复制到更永久的位置。更新到 iOS 13 / Xcode 11 后,我遇到了类似的问题。

注意:此答案已修改以符合@mstorsjo 提供的信息,也在此线程中:https ://stackoverflow.com/a/58099385/3220330