[英]How to upload multiple image on firebase using swift?
我只想使用 swift 在 firebase 上上傳多張圖片。我現在正在上傳一張圖片,但無法上傳多張圖片。 這是我的代碼
let photoIdString = NSUUID().uuidString
let storageRef = Storage.storage().reference(forURL: Config.STORAGE_ROOF_REF).child("posts").child(photoIdString)
storageRef.putData(imageData, metadata: nil,completion: {(metadata,error) in
if error != nil {
return
}
let photoUrl = metadata?.downloadURL()?.absoluteString
let ref = Database.database().reference()
let postReference = ref.child("posts")
let newPostId = postReference.childByAutoId().key
let newPostReference = postReference.child(newPostId)
newPostReference.setValue(["photoUrl":photoUrl,"caption":self.textView.text!])
當前沒有直接API可以批量上傳/下載文件。 我們不能使用循環,因為所有任務都是asynchronously
執行的。 我們可以做的是使用遞歸函數。
核心邏輯
let images = [image1, image2, image3, image4]
func uploadImage(forIndex index: Int) {
if index < images.count {
/// Perform uploading
/// After successfully uploading call this method again by increment the **index = index + 1**
return;
}
/// All images have been uploaded successfully
}
完整代碼示例
1.我創建了一個自定義類來上傳文件
import UIKit
import Firebase
class FirFile: NSObject {
/// Singleton instance
static let shared: FirFile = FirFile()
/// Path
let kFirFileStorageRef = Storage.storage().reference().child("Files")
/// Current uploading task
var currentUploadTask: StorageUploadTask?
func upload(data: Data,
withName fileName: String,
block: @escaping (_ url: String?) -> Void) {
// Create a reference to the file you want to upload
let fileRef = kFirFileStorageRef.child(fileName)
/// Start uploading
upload(data: data, withName: fileName, atPath: fileRef) { (url) in
block(url)
}
}
func upload(data: Data,
withName fileName: String,
atPath path:StorageReference,
block: @escaping (_ url: String?) -> Void) {
// Upload the file to the path
self.currentUploadTask = path.putData(data, metadata: nil) { (metaData, error) in
let url = metaData?.downloadURL()?.absoluteString
block(url)
}
}
func cancel() {
self.currentUploadTask?.cancel()
}
}
2.在這里我們如何使用
首先,為主要功能創建一個完成塊,當您成功上傳所有圖像時,它將通知您。
/// This is your images array
let images = [image1, image2, image3, image4]
/// Here is the completion block
typealias FileCompletionBlock = () -> Void
var block: FileCompletionBlock?
以下是兩個函數,第一個是第一個函數,它將開始上載,第二個是遞歸,如果有下一個圖像可以上載,它將調用自身。
func startUploading(completion: @escaping FileCompletionBlock) {
if images.count == 0 {
completion()
return;
}
block = completion
uploadImage(forIndex: 0)
}
func uploadImage(forIndex index:Int) {
if index < images.count {
/// Perform uploading
let data = UIImagePNGRepresentation(images[index])!
let fileName = String(format: "%@.png", "yourUniqueFileName")
FirFile.shared.upload(data: data, withName: fileName, block: { (url) in
/// After successfully uploading call this method again by increment the **index = index + 1**
print(url ?? "Couldn't not upload. You can either check the error or just skip this.")
self.uploadImage(forIndex: index + 1)
})
return;
}
if block != nil {
block!()
}
}
最后是帶有完成塊的主要功能
startUploading {
/// All the images have been uploaded successfully.
}
編輯新Firebase的“上傳”功能:
唯一的區別是下載URL的方式。 這是相同的新Firebase文檔 。
func upload(data: Data,
withName fileName: String,
atPath path:StorageReference,
block: @escaping (_ url: String?) -> Void) {
// Upload the file to the path
self.currentUploadTask = path.putData(data, metadata: nil) { (metaData, error) in
guard let metadata = metadata else {
// Uh-oh, an error occurred!
block(nil)
return
}
// Metadata contains file metadata such as size, content-type.
// let size = metadata.size
// You can also access to download URL after upload.
path.downloadURL { (url, error) in
guard let downloadURL = url else {
// Uh-oh, an error occurred!
block(nil)
return
}
block(url)
}
}
}
使用新的並發 API 和更新的 Firebase API 這變得簡單多了。
func someUpload(someImagesData: [Data]) async throws -> [String] {
// your path
let storageRef = storageRoot.child("somePath")
return try await withThrowingTaskGroup(of: String.self) { group in
// the urlStrings you are eventually returning
var urlStrings = [String]()
// just using index for testing purposes so each image doesnt rewrites itself
// of course you can also use a hash or a custom id instead of the index
// looping over each image data and the index
for (index, data) in someImagesData.enumerated() {
// adding the method of storing our image and retriving the urlString to the task group
group.addTask(priority: .background) {
let _ = try await storageRef.child("\(index)").putDataAsync(data)
return try await storageRef.child("\(index)").downloadURL().absoluteString
}
}
for try await uploadedPhotoString in group {
// for each task in the group, add the newly uploaded urlSting to our array...
urlStrings.append(uploadedPhotoString)
}
// ... and lastly returning it
return urlStrings
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.