In iOS 14 Apple has introduced PHPickerViewController where user has access to provide permission to all photo library videos or selected videos. In first case when we provide permission to all videos, we are able to get videos from photo library and able to convert it into the video-data to send it to backend server.

But in second case when user provide permission to selected videos, In this scenario we are able to get the videos from the photo library ,but unable to convert it into the data from local video url.At that time data is always getting nil.

We have used below code to retrieve video from photo library url and converted it into the data.

// MARK: PHPickerViewControllerDelegate Methods
extension PhotoPickerVC: PHPickerViewControllerDelegate {
    
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        // Always dismiss the picker first
        dismiss(animated: true)
        if !results.isEmpty {
            guard let itemProvider = results.first?.itemProvider else { return }
            
            itemProvider.loadItem(forTypeIdentifier: "public.movie", options: nil) { [weak self] (fileURL, _) in
                DispatchQueue.main.async {
                    guard let videoURL = fileURL as? URL, let _ = self else { return }
                    do {
                        //mediaURL video loading
                        print(videoURL)
                        let VideoData = try Data(contentsOf: videoURL, options: Data.ReadingOptions.alwaysMapped)
                        print(VideoData)
                    } catch _ {
                        print("Received nil VideoData")
                    }
                }
            }
            
        }
    }
}
2

There are 2 best solutions below

2
On

This line is wrong:

itemProvider.loadItem(forTypeIdentifier: "public.movie", options: nil) { [weak self] (fileURL, _) in

You should not be trying to load any item. You can't hold a video in memory! You should be asking the provider to save the data to disk. I use this sort of code:

let movie = UTType.movie.identifier
itemProvider.loadFileRepresentation(forTypeIdentifier: movie) { url, err in

Note that you must immediately retrieve the URL, because this is a temporary location and the file will be deleted. If you want to preserve the file on disk, you must copy it off synchronously (on a background thead) to somewhere else.

Similarly, do not read the data from the file directly into memory. You can play the video from disk once you have preserved it; that's what it is for.

0
On

You can use like this type of

 func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
                    
        guard let provider = results.first?.itemProvider else { return }
        
        provider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { url, err in
            if let url = url {
                
                print("video url \(url)")
                
            }
        }
        
        if provider.canLoadObject(ofClass: UIImage.self) {
            provider.loadObject(ofClass: UIImage.self) { image, _ in
                self.parent.image = image as? UIImage
            }
        }
    }