I need to save a video file to a temp directory and save the reference to it URL. Currently I have tried using fileManager to create a temp directory and then createFile(atPath: tempDirString, contents: vidData, attributes: nil). But I dont/am not able to save the full reference to the file.
What I have tried:
PHCachingImageManager().requestAVAsset(forVideo: (cell?.assetPH)!, options: nil) { (avAsset, _, _) in
if let avAsset = avAsset {
print(avAsset, " the avasset?")
// vidAVAsset = avAsset
let avPlayerItem = AVPlayerItem(asset: avAsset)
let avPlayer = AVPlayer(playerItem: avPlayerItem)
print(avPlayer, "<-- good?")
let finalURL = self.urlOfCurrentlyPlayingInPlayer(player: avPlayer)
print(finalURL, "<-- finalURL YEAH EYAHY YEAH?!?!?")
// newUserTakenVideo.videoURL = finalURL
let url = self.addVidToTempURL(vidURL: finalURL!)
newUserTakenVideo.videoURL = url
// let newUserTakenVideo = SelectedMedia(videoURL: finalURL, phAsset: (cell?.assetPH)!, thumbnailImg: (cell?.imageView.image)!, uniqueCellID: indexPath)
// GlobalSharedData.shared.arrayOfCurrentCreateMedia.append(newUserTakenVideo)
} else {
print("did noot work")
}
}
This is the function called:
func addVidToTempURL(vidURL: URL) -> URL? {
let fileManager = FileManager.default
let tempDir = fileManager.temporaryDirectory
let tempDirString = tempDir.path
do {
print( "tempDir: \(tempDir)" )
print( "tempDirString: \(tempDirString)" )
if fileManager.fileExists(atPath: tempDirString ) {
print( "tempDir exists" )
do {
try fileManager.createDirectory( at: tempDir, withIntermediateDirectories: true, attributes: nil )
print( "tempDir created" )
if fileManager.fileExists(atPath: tempDirString ) {
print( "tempDir exists" )
let vidData = try Data(contentsOf: vidURL)
fileManager.createFile(atPath: tempDirString, contents: vidData, attributes: nil)
print(tempDirString, " the stringfsdsda")
// fileManager.urls(for: fileManager.temporaryDirectory, in: fileManager.)
let url = URL(string: tempDirString)
return url
} else {
print( "tempDir STILL DOES NOT exist" )
return nil
}
} catch {
print( "tempDir NOT created" )
return nil
}
} else {
print( "tempDir DOES NOT exist" )
do {
try fileManager.createDirectory( at: tempDir, withIntermediateDirectories: true, attributes: nil )
print( "tempDir created" )
if fileManager.fileExists(atPath: tempDirString ) {
print( "tempDir exists" )
let vidData = try Data(contentsOf: vidURL)
fileManager.createFile(atPath: tempDirString, contents: vidData, attributes: nil)
print(tempDirString, " the fsdfdsdfsdfsfsd")
let url = URL(string: tempDirString)
return url
} else {
print( "tempDir STILL DOES NOT exist" )
return nil
}
} catch {
print( "tempDir NOT created" )
return nil
}
}
}
}
How can I get a URL reference to this files location?
I appreciate any help and can add more information if needed. Thanks, me
Since you don't seem to want your file to be visible to users or persisted between app launches, the Temporary directory
sounds perfectly fine for your use case:
var tempVideoFileUrl: URL {
return FileManager.default.temporaryDirectory.appendingPathComponent("my_video_name")
}
func storeVideoToTemporaryFolder(videoData: Data) {
guard !FileManager.default.fileExists(atPath: tempVideoFileUrl.path) else {
return
}
do {
try videoData.write(to: tempVideoFileUrl)
}
catch {
fatalError()
}
}
func loadVideoFromTemporaryFolder() -> Data? {
if let data = try? Data(contentsOf: tempVideoFileUrl) {
return data
}
return nil
}
Worth mentioning though, the system may (and most likely will) purge this directory after the app is exited. It's recommended that you remove any temporary directories/files after they're no longer needed.
So in your case, you can simply remove it once you finished uploading to Firebase Storage:
func deleteVideoFromTemporaryFolder() {
do {
try FileManager.default.removeItem(at: videoFileUrl)
}
catch {
fatalError()
}
}
If you prefer to keep your file around between app launches though, you could use Application Support directory
. But since Application Support and Documents directories gets automatically backed up, you may want to exclude your file from iCloud backup by setting its URL's isExcludedFromBackupKey
key:
var applicationSupportVideoFileUrl: URL {
let applicationSupportFolderUrl = try! FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
return applicationSupportFolderUrl.appendingPathComponent("my_video_name")
}
func excludeFromCloudBackup(url: URL) {
var targetUrl = url
var isAlreadyExcludedFromBackup: Bool
do {
let storedRessourceValues = try targetUrl.resourceValues(forKeys: [URLResourceKey.isExcludedFromBackupKey])
isAlreadyExcludedFromBackup = storedRessourceValues.isExcludedFromBackup ?? false
}
catch {
fatalError()
}
guard !isAlreadyExcludedFromBackup else {
return
}
var ressourceValues = URLResourceValues()
ressourceValues.isExcludedFromBackup = true
do {
try targetUrl.setResourceValues(ressourceValues)
}
catch {
fatalError()
}
}
Edit: To get the data from your PHAsset, this should work:
import Photos
func loadVideoData(phAsset: PHAsset, completion: @escaping (Data?)->()) {
guard phAsset.mediaType == .video else {
return completion(nil)
}
let options = PHVideoRequestOptions()
options.isNetworkAccessAllowed = true
options.deliveryMode = .highQualityFormat
PHCachingImageManager().requestAVAsset(forVideo: phAsset, options: options) { (avAsset, _, _) in
guard let avUrlAsset = avAsset as? AVURLAsset else {
return
}
var videoData: Data?
do {
videoData = try Data(contentsOf: avUrlAsset.url)
} catch {
fatalError()
}
DispatchQueue.main.async {
completion(videoData)
}
}
}
Then simply call this method and store your video in the Temporary folder:
loadVideoData(phAsset: yourPhAsset) { [weak self] videoData in
guard let strongSelf = self else { return }
guard let videoData = videoData else {
return
}
strongSelf.storeVideoToTemporaryFolder(videoData: videoData)
}