iOS 13添加了“修剪".从UIImagePickController选择的文件的前缀 [英] iOS 13 adds "trim." prefix to files selected from UIImagePickController

查看:130
本文介绍了iOS 13添加了“修剪".从UIImagePickController选择的文件的前缀的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从照片中选择文件时,iOS 13添加trim.前缀:

iOS 13 adds a trim. prefix when selecting a file from Photos:

file:///private/var/mobile/Containers/Data/PluginKitPlugin/FPDLKFHEQ-4T56-3456-HTE2-39EK2KDJUR/tmp/trim.DFLSPD0F-32RE-UYI8-DFHA-DPFLEOW098UH.MOV

在iOS-13之前,是这样的:

Before iOS-13 was like this:

file:///private/var/mobile/Containers/Data/PluginKitPlugin/FPDLKFHEQ-4T56-3456-HTE2-39EK2KDJUR/tmp/DFLSPD0F-32RE-UYI8-DFHA-DPFLEOW098UH.MOV

当将文件URL传递到alamofire以将文件上传到后端服务器时,这是一个问题.它导致未知错误",并且上传失败.也许alamofire在使用这个小前缀时遇到了麻烦?

This is an issue when passing the file URL to alamofire to upload the file to a backend server. It causes an "unknown error" and the upload fails. Perhaps alamofire is having trouble with that little prefix?

对此有什么解决办法吗?

Is there any solution for this?

推荐答案

是的,这里的人们遇到了同一问题 .我会扩展答案.

Yes, here people have faced the same issue. I will extend the answer.

您可能需要将该视频复制到临时文件夹中,因此请使用UIImagePickerControllerDelegate的方法:

You probably need to copy that video into the temporary folder, so in your UIImagePickerControllerDelegate's method:

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
    if let mediaType = info[.mediaType] as? String,
        mediaType == "public.movie",
        let trimVideoURL = info[.mediaURL] as? URL {
        if #available(iOS 13, *) {
            // 1
            let urlSlices = trimVideoURL.relativeString.split(separator: ".")
            // 2
            let tempDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
            // 3
            let targetFileURL = tempDirectoryURL.appendingPathComponent(String(urlSlices[1])).appendingPathExtension(String(urlSlices[2]))
            do {
                // 4
                try FileManager.default.copyItem(at: trimVideoURL, to: targetFileURL)
            } catch {
                print(error.localizedDescription)
            }
            // use the video file via targetFileURL path
        }
    }
}

  1. 这里有trimVideURL,需要用.进行切片 file:///private/var/mobile/Containers/Data/PluginKitPlugin/ECD6D7FD-35A8-47E2-8323-808454A32C37/tmp/trim.919BDBB7-E711-49AA-BB84-89E9B0416045.MOV

创建临时目录:
file:///private/var/mobile/Containers/Data/Application/FCD3E053-82DF-4EAE-86BA-4C65880D5B90/tmp/

Create temporary directory:
file:///private/var/mobile/Containers/Data/Application/FCD3E053-82DF-4EAE-86BA-4C65880D5B90/tmp/

在临时文件夹中编写目标文件名:file:///private/var/mobile/Containers/Data/Application/FCD3E053-82DF-4EAE-86BA-4C65880D5B90/tmp/919BDBB7-E711-49AA-BB84-89E9B0416045.MOV

Compose the target filename in temporary folder: file:///private/var/mobile/Containers/Data/Application/FCD3E053-82DF-4EAE-86BA-4C65880D5B90/tmp/919BDBB7-E711-49AA-BB84-89E9B0416045.MOV

最后使用FileManager

准备就绪后,您可以使用以下方法删除文件:

And when you ready, you could delete the file using:

do {
    try FileManager.default.removeItem(at: targetFileURL)
} catch {
    print(error.localizedDescription)
}

关于临时文件的好文章

此外,您可以将该测试项目用作参考,只需将其复制到新创建的项目中即可测试功能:

Also, you could use this test project as a reference, just copy it into new created project to test out functionality:

import UIKit
import WebKit

class ViewController: UIViewController, UINavigationControllerDelegate {
    var imageView: UIImageView!
    var videoView: WKWebView!
    var selectButton: UIButton!
    var deleteButton: UIButton!

    var pickerController: UIImagePickerController?
    var targetFileURL: URL?

    override func viewDidLoad() {
        super.viewDidLoad()
        configureUI()
        setupPickerController()
    }

    func configureUI() {
        imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        videoView = WKWebView()
        videoView.translatesAutoresizingMaskIntoConstraints = false
        selectButton = UIButton(type: .system)
        selectButton.setTitle("Select", for: .normal)
        selectButton.addTarget(self, action: #selector(showImagePicker), for: .touchUpInside)
        selectButton.translatesAutoresizingMaskIntoConstraints = false
        deleteButton = UIButton(type: .system)
        deleteButton.setTitle("Delete", for: .normal)
        deleteButton.addTarget(self, action: #selector(deleteCurrentTempFile), for: .touchUpInside)
        deleteButton.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(imageView)
        view.addSubview(videoView)
        view.addSubview(selectButton)
        view.addSubview(deleteButton)

        imageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        imageView.heightAnchor.constraint(equalToConstant: 250.0).isActive = true

        videoView.topAnchor.constraint(equalTo: imageView.bottomAnchor).isActive = true
        videoView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        videoView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        videoView.heightAnchor.constraint(equalTo: imageView.heightAnchor).isActive = true

        deleteButton.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        deleteButton.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        deleteButton.heightAnchor.constraint(equalToConstant: 60.0).isActive = true
        deleteButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true

        selectButton.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        selectButton.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        selectButton.heightAnchor.constraint(equalTo: deleteButton.heightAnchor).isActive = true
        selectButton.bottomAnchor.constraint(equalTo: deleteButton.topAnchor).isActive = true

        view.layoutIfNeeded()
    }

    func setupPickerController() {
        self.pickerController = UIImagePickerController()
        self.pickerController?.delegate = self
        if let mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary) {
            self.pickerController?.mediaTypes = mediaTypes
        }
    }

    private func action(for type: UIImagePickerController.SourceType, title: String) -> UIAlertAction? {
        guard UIImagePickerController.isSourceTypeAvailable(type) else {
            return nil
        }

        return UIAlertAction(title: title, style: .default) { [unowned self] _ in
            self.pickerController?.sourceType = type
            if let pickerController = self.pickerController {
                self.present(pickerController, animated: true)
            }
        }
    }

    @IBAction func showImagePicker() {
        let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        if let action = self.action(for: .photoLibrary, title: "Photo library") {
            alertController.addAction(action)
        }
        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        present(alertController, animated: true)
    }

    @IBAction func deleteCurrentTempFile() {
        if let url = targetFileURL,
            FileManager.default.fileExists(atPath: url.path) {
            removeTemporaryFile(at: url)
        }
    }

    func didSelectMedia(image: UIImage?, videoURL: URL?) {
        if let image = image {
            imageView.image = image
        } else if let videoURL = videoURL {
            let request = URLRequest(url: videoURL)
            videoView.load(request)
            targetFileURL = videoURL
        }
    }

    // remove it when you done
    func removeTemporaryFile(at url: URL) {
        do {
            try FileManager.default.removeItem(at: url)
        } catch {
            print(error.localizedDescription)
        }
        targetFileURL = nil
    }
}

extension ViewController: UIImagePickerControllerDelegate {

    public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        if let mediaType = info[.mediaType] as? String {
            if mediaType == "public.movie", let trimVideoURL = info[.mediaURL] as? URL {
                if #available(iOS 13, *) {
                    let urlSlices = trimVideoURL.relativeString.split(separator: ".")
                    let tempDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
                    let targetFileURL = tempDirectoryURL.appendingPathComponent(String(urlSlices[1])).appendingPathExtension(String(urlSlices[2]))
                    do {
                        try FileManager.default.copyItem(at: trimVideoURL, to: targetFileURL)
                    } catch {
                        print(error.localizedDescription)
                    }
                    self.didSelectMedia(image: nil, videoURL: targetFileURL)
                } else {
                    self.didSelectMedia(image: nil, videoURL: trimVideoURL)
                }
            } else if mediaType == "public.image", let image = info[.originalImage] as? UIImage {
                self.didSelectMedia(image: image, videoURL: nil)
            }
        }
        picker.dismiss(animated: true, completion: nil)
    }
}

这篇关于iOS 13添加了“修剪".从UIImagePickController选择的文件的前缀的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆