I'm trying to get the original video file creation date when importing a video using PhotosPicker, and am unable to get anything other than the newly copied file's creation date which will always be the moment the file was imported.
I have tried various ways using the PhotosPicker but haven't had any success in getting the actual date. I have also attempted to get the original video creation date with PHPhotoPicker and UIImagePicker and have had the same result. It should be extremely easy to get but I can't find an example anywhere.
Here is a minimal example:
import SwiftUI
import PhotosUI
struct ContentView: View {
@State var showPicker = false
@State var selectedItem: PhotosPickerItem?
var body: some View {
VStack {
Button("PHPicker") {
showPicker.toggle()
}
.photosPicker(isPresented: $showPicker, selection: $selectedItem, matching: .videos)
.padding()
.onChange(of: selectedItem) { newValue in
if let newValue {
Task {
do {
let pickedMovie = try await newValue.loadTransferable(type: VideoPickerTransferable.self)
}
}
}
}
}
}
}
#Preview {
ContentView()
}
struct VideoPickerTransferable: Transferable {
let videoUrl: URL
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(contentType: .movie) { exportingFile in
return .init(exportingFile.videoUrl)
} importing: { receivedTransferredFile in
let originalFile = receivedTransferredFile.file
print(try FileManager.default.attributesOfItem(atPath: originalFile.path())[FileAttributeKey.creationDate])
let copiedFile = URL.documentsDirectory.appending(path: "videoPicker.mov")
if FileManager.default.fileExists(atPath: copiedFile.path()) {
try FileManager.default.removeItem(at: copiedFile)
}
try FileManager.default.copyItem(at: originalFile, to: copiedFile)
return .init(videoUrl: copiedFile)
}
}
}
You can use the rendition of photosPicker
that takes a photoLibrary
parameter. When you do that, the PhotosPickerItem
will include a itemIdentifier
that you can use with PHAsset.fetchAssets
:
struct ContentView: View {
@State var showPicker = false
@State var selectedItem: PhotosPickerItem?
var body: some View {
VStack {
Button("Photo picker") {
showPicker.toggle()
}
.photosPicker(
isPresented: $showPicker,
selection: $selectedItem,
matching: .videos,
photoLibrary: .shared()
)
.padding()
.onChange(of: selectedItem) {
guard
let identifier = selectedItem?.itemIdentifier,
let asset = PHAsset.fetchAssets(
withLocalIdentifiers: [identifier],
options: nil
).firstObject,
let creationDate = asset.creationDate
else {
print("unable to fetch date")
return
}
print(creationDate)
}
}
}
}
By the way, you will need to add a “Privacy - Photo Library Usage Description”, i.e., NSPhotoLibraryUsageDescription
, to your Info.plist
.