My function ends before all data can be retrieved from the fire storage and returns empty. How can I get the data before returning?
Code:
func listItem() -> [imageitem]{
let storage = Storage.storage()
let storageRef = storage.reference().child("images/image")
var array = [imageitem]()
storageRef.listAll { (result, error) in
if let error = error {
print("error")
print(error)
}
print("storagereference")
result?.items.forEach({ StorageReference in
print(StorageReference)
print(StorageReference.name)
StorageReference.getData(maxSize: 5*1024*1024) {data, error in
if error == nil && data != nil{
if let image = UIImage(data: data!){
let element = imageitem(title: StorageReference.name, image: Image(uiImage: image))
array.append(element)
print(array)
}
}
}
})
print("end",array)
}
return array
}
Console:
storagereference
gs://proj-69776.appspot.com/images/image/gorilla.jpg
gorilla.jpg
gs://proj-69776.appspot.com/images/image/test.jpg
test.jpg
end []
[proj.ListView.imageitem(title: "test.jpg", image: SwiftUI.Image(provider: SwiftUI.ImageProviderBox<__C.UIImage>))]
[proj.ListView.imageitem(title: "test.jpg", image: SwiftUI.Image(provider: SwiftUI.ImageProviderBox<__C.UIImage>)), proj.ListView.imageitem(title: "gorilla.jpg", image: SwiftUI.Image(provider: SwiftUI.ImageProviderBox<__C.UIImage>))]
adding an await
before the addData
gives me an error
Cannot pass function of type '(StorageReference) async -> Void' to parameter expecting synchronous function type
You cannot return data that is loaded asynchronously with a return
statement like that, because the return
runs well before you ever append any element to the array. If you set breakpoints and run the code in a debugger you can most easily validate that.
Instead, you'll want to pass in a closure/callback or use a dispatch queue to get the value out of your function into the calling context.
For examples of how to do this, see: