How load Video with New(iOS 16) PhotosPicker? loadTransferable(type:)

I use loadFileRepresentation(forTypeIdentifier:completionHandler:) to load video with PHPickerViewController

What can I use load video with?

// my sample code

func loadPhoto(pickerItem: PhotosPickerItem) async throws -> Photo {

    if let livePhoto = try await pickerItem.loadTransferable(type: PHLivePhoto.self) {

      let photo: Photo = .init(id: pickerItem.itemIdentifier, item: livePhoto)

      return photo

    } else if let url = try await pickerItem.loadTransferable(type: URL.self) {

      let photo: Photo = .init(id: pickerItem.itemIdentifier, item: url)

      return photo

    } else if let data = try await pickerItem.loadTransferable(type: Data.self) {

      let photo: Photo = .init(id: pickerItem.itemIdentifier, item: data)

      return photo

    }



    throw PhotoError.load

  }

Accepted Reply

This problem fixed in iOS 16 beta 5. thanks

https://github.com/zunda-pixel/SamplePhotosPicker

Replies

You should define you own model object conforming to the Transferable protocol. For example:

struct Movie: Transferable {
    let url: URL
    static var transferRepresentation: some TransferRepresentation {
        FileRepresentation(contentType: .movie) { movie in
            SentTransferredFile($0.url)
        } importing: { received in
            let copy: URL = URL(fileURLWithPath: "<#...#>")
            try FileManager.default.copyItem(at: received.file, to: copy)
            return Self.init(url: copy)
        }
    }
}

Then you can write:

let movie = try await pickerItem.loadTransferable(type: Movie.self)

For more information: https://developer.apple.com/documentation/coretransferable/filerepresentation

  • So when importing, it creates a copy of my video in the caches directory, then I have to make another copy of it. What if I'm importing a big video file. In line 8 of your example, do we then have 3 instances of the same video file on the hard disk wasting space (original, copy 1, copy 2)? Or is it no problem thanks to copy-on-write capabilities of the file system?

  • With this approach it takes a very long time(up to minutes sometimes) for long videos when I do item.loadTransferable(type: Movie.self). I'm testing on iOS 17

Add a Comment

FileRepresentation.importing's 'receivedData' is already deleted. when I use.

import CoreTransferable

struct Movie: Transferable {

  let url: URL

  static var transferRepresentation: some TransferRepresentation {
    FileRepresentation(contentType: .movie) { movie in
      SentTransferredFile(movie.url)
    } importing: { receivedData in
      let fileName = receivedData.file.lastPathComponent

      let copy: URL =  FileManager.default.temporaryDirectory.appendingPathComponent(fileName)

      try FileManager.default.copyItem(at: receivedData.file, to: copy)

      return .init(url: copy)
    }
  }
}
Error Domain=NSCocoaErrorDomain Code=260 "The file “IMG_0458.mov” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/private/var/mobile/Containers/Data/Application/D2E2AF9F-E879-4792-89CE-E7FB6B1B8234/tmp/.com.apple.Foundation.NSItemProvider.flbzCW/IMG_0458.mov, NSUnderlyingError=0x28389eeb0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
  • Thanks for the report. This is tracked by 96296011.

Add a Comment

This problem fixed in iOS 16 beta 5. thanks

https://github.com/zunda-pixel/SamplePhotosPicker