在 iOS 终止任务之前,如何让非常大的文件有时间上传到 firebase?
How do you allow very large files to have time to upload to firebase before iOS terminates the task?
我有一个视频共享应用程序,当您将视频保存到 firebase 存储时,它非常适合大约 1 分钟或更短的视频。
我遇到的问题是,当我尝试 post 更长的视频(1 分钟或更长)时,它永远不会保存到 firebase。
我唯一能想到的就是我收到的这个错误,这个错误只在我点击保存按钮后大约 30 秒出现:
[BackgroundTask] Background Task 101 ("GTMSessionFetcher-firebasestorage.googleapis.com"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
这是我将视频保存到 firebase 的代码。
func saveMovie(path: String, file: String, url: URL) {
var backgroundTaskID: UIBackgroundTaskIdentifier?
// Perform the task on a background queue.
DispatchQueue.global().async {
// Request the task asseration and save the ID
backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: "Finish doing this task", expirationHandler: {
// End the task if time expires
UIApplication.shared.endBackgroundTask(backgroundTaskID!)
backgroundTaskID = UIBackgroundTaskIdentifier.invalid
})
// Send the data synchronously
do {
let movieData = try Data(contentsOf: url)
self.storage.child(path).child("\(file).m4v").putData(movieData)
} catch let error {
fatalError("Error saving movie in saveMovie func. \(error.localizedDescription)")
}
//End the task assertion
UIApplication.shared.endBackgroundTask(backgroundTaskID!)
backgroundTaskID = UIBackgroundTaskIdentifier.invalid
}
}
关于如何让我的视频有时间上传的任何建议?
想了很久终于搞明白了...
您所要做的就是使用 .putFile("FileURL")
而不是 .putdata("Data")
。 Firebase 文档说上传大文件时应该使用 putFile()
而不是 putData()
。
但困难的部分是由于某些原因你不能直接上传你从 didFinishPickingMediaWithInfo
函数获得的电影 URL 并且 firebase 只会给你一个错误。所以我做的是获取电影数据,将电影数据保存到文件管理器中的路径,然后使用文件管理器路径 URL 直接上传到对我有用的 firebase。
//Save movie to Firestore
do {
// Convert movie to Data.
let movieData = try Data(contentsOf: movie)
// Get path so we can save movieData into fileManager and upload to firebase because movie URL does not work, but fileManager url does work.
guard let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(postId!) else { print("Error saving to file manager in addPost func"); return }
do {
try movieData.write(to: path)
// Save the file manager url file to firebase storage
Storage.storage().reference().child("Videos").child("\(postId!).m4v").putFile(from: path, metadata: nil) { metadata, error in
if let error = error {
print("There was an error \(error.localizedDescription)")
} else {
print("Video successfully uploaded.")
}
// Delete video from filemanager because it would take up too much space to save all videos to file manager.
do {
try FileManager.default.removeItem(atPath: path.path)
} catch let error {
print("Error deleting from file manager in addPost func \(error.localizedDescription)")
}
}
} catch let error {
print("Error writing movieData to firebase \(error.localizedDescription)")
}
} catch let error {
print("There was an error adding video in addPost func \(error.localizedDescription)")
}
我有一个视频共享应用程序,当您将视频保存到 firebase 存储时,它非常适合大约 1 分钟或更短的视频。
我遇到的问题是,当我尝试 post 更长的视频(1 分钟或更长)时,它永远不会保存到 firebase。
我唯一能想到的就是我收到的这个错误,这个错误只在我点击保存按钮后大约 30 秒出现:
[BackgroundTask] Background Task 101 ("GTMSessionFetcher-firebasestorage.googleapis.com"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
这是我将视频保存到 firebase 的代码。
func saveMovie(path: String, file: String, url: URL) {
var backgroundTaskID: UIBackgroundTaskIdentifier?
// Perform the task on a background queue.
DispatchQueue.global().async {
// Request the task asseration and save the ID
backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: "Finish doing this task", expirationHandler: {
// End the task if time expires
UIApplication.shared.endBackgroundTask(backgroundTaskID!)
backgroundTaskID = UIBackgroundTaskIdentifier.invalid
})
// Send the data synchronously
do {
let movieData = try Data(contentsOf: url)
self.storage.child(path).child("\(file).m4v").putData(movieData)
} catch let error {
fatalError("Error saving movie in saveMovie func. \(error.localizedDescription)")
}
//End the task assertion
UIApplication.shared.endBackgroundTask(backgroundTaskID!)
backgroundTaskID = UIBackgroundTaskIdentifier.invalid
}
}
关于如何让我的视频有时间上传的任何建议?
想了很久终于搞明白了...
您所要做的就是使用 .putFile("FileURL")
而不是 .putdata("Data")
。 Firebase 文档说上传大文件时应该使用 putFile()
而不是 putData()
。
但困难的部分是由于某些原因你不能直接上传你从 didFinishPickingMediaWithInfo
函数获得的电影 URL 并且 firebase 只会给你一个错误。所以我做的是获取电影数据,将电影数据保存到文件管理器中的路径,然后使用文件管理器路径 URL 直接上传到对我有用的 firebase。
//Save movie to Firestore
do {
// Convert movie to Data.
let movieData = try Data(contentsOf: movie)
// Get path so we can save movieData into fileManager and upload to firebase because movie URL does not work, but fileManager url does work.
guard let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(postId!) else { print("Error saving to file manager in addPost func"); return }
do {
try movieData.write(to: path)
// Save the file manager url file to firebase storage
Storage.storage().reference().child("Videos").child("\(postId!).m4v").putFile(from: path, metadata: nil) { metadata, error in
if let error = error {
print("There was an error \(error.localizedDescription)")
} else {
print("Video successfully uploaded.")
}
// Delete video from filemanager because it would take up too much space to save all videos to file manager.
do {
try FileManager.default.removeItem(atPath: path.path)
} catch let error {
print("Error deleting from file manager in addPost func \(error.localizedDescription)")
}
}
} catch let error {
print("Error writing movieData to firebase \(error.localizedDescription)")
}
} catch let error {
print("There was an error adding video in addPost func \(error.localizedDescription)")
}