How to upload multiple image on firebase using swift?

后端 未结 1 1608
日久生厌
日久生厌 2020-12-10 10:07

I just want to upload multiple image on firebase using swift. I am now uploading one image but unable to upload multiple image. Here is my code

let photoIdSt         


        
相关标签:
1条回答
  • 2020-12-10 10:21

    Currently there is no direct API to uploading/downloading the files in batch. We can not use loop because all the tasks perform asynchronously. What we can do is to use a recursive function.

    Core Logic

    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
    }
    

    Full Code Example

    1. I created a custom class for file uploading

    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. Here how can we use this

    First of all create a completion block for main function which will let you know when all images will be uploaded successfully.

    /// This is your images array
    let images = [image1, image2, image3, image4]
    
    /// Here is the completion block
    typealias FileCompletionBlock = () -> Void
    var block: FileCompletionBlock?
    

    Below are two functions first one is the initial one which will start the uploading and the second one is a recursion which will call itself if there is next image available to upload.

    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!()
          }
    }
    

    And finally here is the main function with completion block

    startUploading {
        /// All the images have been uploaded successfully.
    }
    

    EDIT "upload" function for new Firebase:

    The only difference is the way of getting downloading url. Here is the new Firebase doc on same.

    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)
             }
        }
    }
    
    0 讨论(0)
提交回复
热议问题