Faisal Al Saadi
Faisal Al Saadi

Reputation: 125

uploading/downloading multiple images the right way?

i'm trying to upload or download images using Nuke(framework for downloading and Caching images) And Firebase to upload images as the backend

for single file it's easy to deal with without any problem but for multiple ones i don't really know what to do right i'm having an issues where it don't do it job synchronously it downloads second image before the first one sometimes

i'll show my way of downloading and uploading multiple images

For download i put the code in for-loop

    func downloadImages(completion: (result: [ImageSource]) -> Void){
    var images = [ImageSource]()
    for i in 0...imageURLs.count-1{

        let request = ImageRequest(URL: NSURL(string:imageURLs[i])!)

        Nuke.taskWith(request) { response in
            if response.isSuccess{
        let image = ImageSource(image: response.image!)
                images.append(image)
                if i == self.imageURLs.count-1 {
                    completion(result: images)
                }
            }


        }.resume()


    }

}

And for uploading where the user chooses the images form image picker and return it as NSData array And then perform this code

    func uploadImages(completion: (result: [String]) -> Void){
    let storageRef = storage.referenceForURL("gs://project-xxxxxxxxx.appspot.com/Uploads/\(ref.childByAutoId())")
    var imageUrl = [String]()
    var imgNum = 0



    for i in 0...imageData.count-1 {
        let imagesRef = storageRef.child("\(FIRAuth.auth()?.currentUser?.uid) \(imgNum)")
        imgNum+=1

        let uploadTask =  imagesRef.putData(imageData[i], metadata: nil) { metadata, error in
            if (error != nil) {
                print("error")
                imageUrl = [String]()
                completion(result: imageUrl)
            } else {

                print("uploading")
                // Metadata contains file metadata such as size, content-type, and download URL.
                let downloadURL = metadata!.downloadURL()?.absoluteString
                print(downloadURL)
                imageUrl.append(downloadURL!)
                if i == imageUrl.count-1{ //end of the loop
                    print("completionUpload")
                    completion(result: imageUrl)

                }
            }
        }}

this is good way to do this task ?

what should i do to make each image downloads in order ?

please give me anything that may help example code , link etc ..

Thanks in advance

Upvotes: 0

Views: 1758

Answers (1)

Mike McDonald
Mike McDonald

Reputation: 15953

We highly recommend using Firebase Storage and the Firebase Realtime Database together to accomplish lists of downloads:

Shared:

// Firebase services
var database: FIRDatabase!
var storage: FIRStorage!
...
// Initialize Database, Auth, Storage
database = FIRDatabase.database()
storage = FIRStorage.storage()

Upload:

let fileData = NSData() // get data...
let storageRef = storage.reference().child("myFiles/myFile")
storageRef.putData(fileData).observeStatus(.Success) { (snapshot) in
  // When the image has successfully uploaded, we get it's download URL
  let downloadURL = snapshot.metadata?.downloadURL()?.absoluteString
  // Write the download URL to the Realtime Database
  let dbRef = database.reference().child("myFiles/myFile")
  dbRef.setValue(downloadURL)
}

Download:

let dbRef = database.reference().child("myFiles")
dbRef.observeEventType(.ChildAdded, withBlock: { (snapshot) in
  // Get download URL from snapshot
  let downloadURL = snapshot.value() as! String

  // Now use Nuke (or another third party lib)
  let request = ImageRequest(URL: NSURL(string:downloadURL)!)
  Nuke.taskWith(request) { response in
    // Do something with response
  }

  // Alternatively, you can use the Storage built-ins:
  // Create a storage reference from the URL
  let storageRef = storage.referenceFromURL(downloadURL)
  // Download the data, assuming a max size of 1MB (you can change this as necessary)
  storageRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
    // Do something with data...
  })
})

For more information, see Zero to App: Develop with Firebase, and it's associated source code, for a practical example of how to do this.

Upvotes: 1

Related Questions