1

I have a .mp4 video saved in Firebase and I want to save it to the .cachesDirectory. I want to make sure it is saved and tried to use a do-try block but it wouldn't accept it:

No calls to throwing functions occur within 'try' expression.

How else can I check to see if the file was successfully saved to the .cachesDirectory?

let fbStr = "https://firebasestorage.googleapis.com/v0/b/myApp.appspot.com/o/abcd%277920FHqFBkl7D6j%2F-MC65EFG_qT0KZbdtFhU%2F48127-8C29-4666-96C9-E95BE178B268.mp4?alt=media&token=bf85dcd1-8cee-428e-87bc-91800b7316de"
guard let url = URL(string: fbStr) else { return }
let videoData = NSData(contentsOf: url)
let cachesDir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!

do {
    try videoData?.write(toFile: cachesDir.path, atomically: true)
} catch {
    print("video wasn't saved to cachesDirectory") 
}
Lance Samaria
  • 11,429
  • 8
  • 67
  • 159

1 Answers1

1

Use the write(toFile:) method without automically parameter.

do {
    try videoData?.write(toFile: cachesDir.path, options: .atomic)
} catch {
    print("video wasn't saved to cachesDirectory")
}
Frankenstein
  • 13,516
  • 4
  • 12
  • 38
  • thanks, it worked. It says I can't accept the answer for 9 mins. As soon as it is ready I'll accept it. Why can't I use the **atomically** param? – Lance Samaria Jul 13 '20 at 09:39
  • It's a different method that throws. You could use atomically. Check the update. – Frankenstein Jul 13 '20 at 09:42
  • I changed it to use .atomic, thanks. Like 5 more min – Lance Samaria Jul 13 '20 at 09:44
  • @LanceSamaria Note that you are supposed to append a file name to your directory url and using .atomic option will override the file if it exists already at the location. Btw there is a method that writes to the url `write(to: fileURL, options: .atomic)` – Leo Dabus Jul 13 '20 at 15:56
  • @LeoDabus can you give me an example? Isn’t the firebase string the file name itself? – Lance Samaria Jul 13 '20 at 15:58
  • `let fileURL = cachesDir.appendingPathComponent("filename.ext")` – Leo Dabus Jul 13 '20 at 16:00
  • Also note that NSData(contentsOf: url) it is not mean to use with non local resources urls. It will freeze your app if there is no internet connection. You should use URLSession dataTask or downloadTask (if you would like to download while your app is in the background) – Leo Dabus Jul 13 '20 at 16:02
  • @LeoDabus, I use NSData(contentsOf: url) on a background queue, will it still freeze the app? This is what I do, user paginates, once the data is pulled from a firebase endpoints like "postsRef", in the data model, I check to see if there is a videoUrl and if there is I convert it to NSData on a global queue, then save it to the .cahcesDirectory. This way if the user plays the video, it'll play faster from the device rather than playing it from the server. I use the **DispatchQueue.global().async** part of this answer https://stackoverflow.com/a/45062989/4833705 – Lance Samaria Jul 13 '20 at 21:09
  • You should never use this method for this purpose (it doesn’t matter if it is on a background queue or not. You should use the appropriate method as I have mentioned above – Leo Dabus Jul 13 '20 at 21:11
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/217760/discussion-between-lance-samaria-and-leo-dabus). – Lance Samaria Jul 13 '20 at 21:11
  • Check the important on documentation https://developer.apple.com/documentation/foundation/nsdata/1407864-init – Leo Dabus Jul 13 '20 at 21:12
  • @LeoDabus I used url session but it's moving slow. https://stackoverflow.com/questions/62885545/urlsession-moving-slow-when-caching-a-firebase-video-url – Lance Samaria Jul 13 '20 at 22:58
  • Why are you downloading to memory if you are writing it to disk? Use downloadTask and move the file when it finishes – Leo Dabus Jul 13 '20 at 23:00
  • @LeoDabus Hi, I just got Rich Notifications working and I remembered this thread when you advised me to never use `NSData(contentsOf: url)` and instead use `downloadTask`. When the rich notification image is a url image that needs to be downloaded, I have seen people use both `NSData` and `downloadTack`. For rich notifications, which is better to use? **downloadTask**: https://stackoverflow.com/a/48724927/4833705 or **NSData**: https://stackoverflow.com/a/39103096/4833705. Will using `NSData` make a difference? – Lance Samaria Feb 21 '21 at 02:08