Swift上传文件至Firebase Storage后下载保存异常问题
问题描述
- 我用Swift开发了一个功能:将本地设备的文件以原始二进制格式上传至Firebase Storage,上传完成后在Firebase存储中能看到文件,且文件大小显示正确。
- 现在通过文件的Firebase Storage下载URL尝试将文件下载到本地设备,期望文件能出现在iOS「Files」应用的下载目录中。点击下载按钮后没有报错,但文件并未出现在「Files」里;不过把该URL粘贴到谷歌浏览器中,文件可以自动下载。
- 之后我在「Files」中找到了下载的文件,但点击打开后仅显示文档ID和字节大小,在Mac上查看该文件也无法看到真实的文本内容。我知道下载逻辑存在问题,但不确定上传环节是否也有问题?
原始代码
import SwiftUI import UniformTypeIdentifiers import Firebase import FirebaseStorage struct FilePicker: View { @State private var showPicker = false // 示例中使用的是Firebase Storage中存储的PDF文档URL @State private var finalURL: String? = "https://firebasestorage.googleapis.com:443/v0/b/hustle-85b6c.appspot.com/o/files%2FF425B036-D3DC-4B8A-9CE0-D7A8893D5466?alt=media&token=5a33534d-ea81-45c2-8113-042a9d021d05" var body: some View { VStack { Spacer() if let url = finalURL { Button(action: { downloadFile(urlS: url) }, label: { Text("download") }) } Button(action: { showPicker.toggle() }, label: { Image(systemName: "paperclip") .padding() .foregroundStyle(.blue) .background(.gray) .clipShape(Circle()) }) Spacer() } .fileImporter(isPresented: $showPicker, allowedContentTypes: [UTType.data]) { result in do { let url = try result.get() let accessing = url.startAccessingSecurityScopedResource() defer { if accessing { url.stopAccessingSecurityScopedResource() } } if let fileData = try? Data(contentsOf: url) { uploadFile(data: fileData, location: "files") { urlS in print(urlS) finalURL = urlS } } } catch { print("File picker error: \(error)") } } } func downloadFile(urlS: String) { guard let url = URL(string: urlS) else { return } let downloadTask = URLSession.shared.dataTask(with: url) { (data, response, error) in if let error = error { print("Error downloading file: \(error)") return } if let data = data { saveFile(data: data, fileName: "download\(UUID().uuidString.prefix(5))") } } downloadTask.resume() } func saveFile(data: Data, fileName: String) { guard let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } let fileURL = documentsURL.appendingPathComponent(fileName) do { try data.write(to: fileURL) print("File saved") } catch { print("Error saving file: \(error)") } } func uploadFile(data: Data, location: String, completion: @escaping (String) -> Void) { let ref = Storage.storage().reference(withPath: "/\(location)/\(NSUUID().uuidString)") ref.putData(data, metadata: nil) { metadata, error in if let err = error { print(err) } ref.downloadURL { (url, error) in guard let downloadURL = url?.absoluteString else { completion("") return } completion(downloadURL) } } } }
更新后的save函数
func saveFile(data: Data, fileName: String, fileExtension: String) { guard let downloadsURL = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first else { return } let fileURL = downloadsURL.appendingPathComponent("\(fileName).\(fileExtension)") do { if !FileManager.default.fileExists(atPath: fileURL.path) { FileManager.default.createFile(atPath: fileURL.path, contents: nil, attributes: nil) } try data.write(to: fileURL) print("File saved") } catch { print("Error saving file: \(error)") } }
内容的提问来源于stack exchange,提问作者Ahmed Zaidan
相关产品推荐
相关产品推荐

