Reputation: 27
I'm trying to upload an image using Firebase Storage. The problem i'm having is when i'm calling my image upload function, the upload task is very slow and it ends up running last in my main function when it is actually called further up.
Is there a way to wait for storageRef.putData to finish before continuing the rest of the function?
Would possibly reducing compression quality from 1 be faster?
Here is my function:
func newImageUrl(){
let key = self.itemId
guard let userID = Auth.auth().currentUser?.uid else { return }
let storageRef = Storage.storage().reference().child(userID).child("SubCategory").child(self.itemTitle!).child(key!).child("ItemImages.jpg")
guard let imageData = self.itemImage.image!.jpegData(compressionQuality: 1) else { return }
print("starting image upload!")
storageRef.putData(imageData, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
return
}
storageRef.downloadURL { (url, error) in
guard let urlStr = url else{
return
}
let urlFinal = (urlStr.absoluteString)
self.imageFinalUrl = urlFinal
}
}
}
UPDATED func --
func newImageUrl(completion:@escaping((String?) -> () )) {
let key = self.itemId
guard let userID = Auth.auth().currentUser?.uid else { completion(nil) ; return }
let storageRef = Storage.storage().reference().child(userID).child("SubCategory").child(self.itemTitle!).child(key!).child("ItemImages.jpg")
guard let imageData = self.itemImage.image!.jpegData(compressionQuality: 1) else { completion(nil) ; return }
print("starting image upload!")
storageRef.putData(imageData, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
return
}
storageRef.downloadURL { (url, error) in
guard let urlStr = url else{
completion(nil)
return
}
let urlFinal = (urlStr.absoluteString)
self.imageFinalUrl = urlFinal
completion(urlFinal)
}
}
}
Example main function:
func updateItemDetail(){
print("this is running 1")
self.newImageUrl { (str) in
print(str)
}
print("this is running 2")
Console prints:
this is running 1
starting image upload!
this is running 2
Optional("https://firebasestorage.googleapis.com/v0/b/.....etc")
Upvotes: 1
Views: 1220
Reputation: 562
UPDATED
There is now a method in firebase storage that you can use to put files asynchronsly and therefore you can simply use await
to wait for the upload to complete.
e.g
let uploadMetadata = try await storageRef.putDataAsync(imageData, metadata: nil)
//Do whatever you want to after completion
Upvotes: 0
Reputation: 100503
You need a completion
func newImageUrl(completion:@escaping((String?) -> () )) {
let key = self.itemId
guard let userID = Auth.auth().currentUser?.uid else { completion(nil) ; return }
let storageRef = Storage.storage().reference().child(userID).child("SubCategory").child(self.itemTitle!).child(key!).child("ItemImages.jpg")
guard let imageData = self.itemImage.image!.jpegData(compressionQuality: 1) else { completion(nil) ; return }
print("starting image upload!")
storageRef.putData(imageData, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
return
}
storageRef.downloadURL { (url, error) in
guard let urlStr = url else{
completion(nil)
return
}
let urlFinal = (urlStr.absoluteString)
self.imageFinalUrl = urlFinal
completion(urlFinal)
}
}
}
Call
newImageUrl { (str) in
print(str)
// do your next work here
}
Upvotes: 3