Retrieve an image from Firebase to an UIimage swift5
There's a number of ways to go about this but a brief description of the issue first:
The return statement within the closure will execute way before that image is downloaded - Firebase functions are asynchronous and code has to be crafted in a way that allows for time to download and get data from the internet. So - don't try to return data from asynchronous functions.
Here's the code re-written with a completion handler. That handler will be called only after the image is fully downloaded.
func getImageEvent (imagePath: String, completion: @escaping(UIImage) -> Void) {
var myImage : UIImageView?
let storageRef = Storage.storage().reference(withPath: imagePath)
storageRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
print(error.localizedDescription)
return
}
if let data = data {
if let myImage = UIImage(data: data) {
completion(myImage)
}
}
}
}
and the key is how to call that function. Note this code awaits the data (UIImage) to be passed back to it within it's closure and lets you know that getting the image was complete.
self.getImageEvent(imagePath: "9U4BoXgBgTTgbbJCz0zy/eventMainImage.jpg", completion: { theImage in
print("got the image!")
})
You should add additional error checking in case the image was not downloaded or myImage was nil. Passing back an error message along with the nil myImage would be one option, or making the object passed back as an optional and then checking for nil within self.downloadImageAtPath
would be another.
How to download or retrieve image from firebase storage in SwiftUI or Swift 5
For swift 5, you can use this :
let Ref = Storage.storage().reference(forURL: yourUrl)
Ref.getData(maxSize: 1 * 1024 * 1024) { data, error in
if error != nil {
print("Error: Image could not download!")
} else {
yourImageView.image = UIImage(data: data!)
}
}
Hope it helps...
Retrieving image from Fire Storage however if the image does not exist the app crashes
I figured the solution out to this issue as well and wanted to post in case any new coders have the same problem. I simply had to add
if error != nil {
print(error!.localizedDescription)
return
}
Full Example
func downloadimages() {
let reference = Storage.storage().reference(withPath: "\("images/"+Auth.auth().currentUser!.uid+"+.jpg")")
reference.downloadURL{(url, error) in
if error != nil {
print(error!.localizedDescription)
return
}
let data = NSData(contentsOf: url!)
let image = UIImage(data: data! as Data)
self.profileimage.image = image
}
}
Async fetching image Firebase Swift 5
You need to use NSCache
for saving and retrieving images. Once the images are fetched from network store it inside the Cache and from the next time load the images from the Cache. Create an instance of NSCache
with keys NSString
and value NSData
because NSCache only allows class types. Here's an example:
Create an image cache outside the cellForItem
method, or you can create it as Global, like this:
let imageCache = NSCache<NSString, NSData>()
And then in cellForItem
method:
if let url = URL(string: rest1.image) {
if let data = imageCache.object(forKey: rest1.image as NSString) {
cell.RestaurantImage.image = UIImage(data: data as Data)
} else {
DispatchQueue.global().async {
if let data = try? Data(contentsOf: url) {
imageCache.setObject(data as NSData, forKey: rest1.image as NSString)
DispatchQueue.main.async {
cell.RestaurantImage.image = UIImage(data: data)
}
}
}
}
}
I have a 'UIImage' and I want to convert it to NSData to upload on firebase storage
You need
func uploadImageToFirebase (_ image:UIImage){
gurad let data = image.pngData() else { return }
..... OR
guard let data = image.jpegData(compressionQuality: 0.5) else { return }
}
discover.uploadImageToFirebase(image)
the error is clear the parameter type is NSData
so you can't pass a UIImage
Closure with FirebaseStorage (UIImage→URL)
The function StorageService.storage
is asynchronous, when there is an image, the function to insert in the firestore is executed without receiving the URL response.
You must place your function to insert in the clousure of StorageService.storage
to get and save the URL of the image
// If Image is Set
if let image = image {
StorageService.storage(image: image, path: .icon, id: uid) { (imageUrl) in
dict["iconUrl"] = imageUrl
Firestore.firestore().collection("users").document(uid).setData(dict) { (error) in
if let error = error {
print(error)
return
}
onSuccess()
}
}
}else {
Firestore.firestore().collection("users").document(uid).setData(dict) { (error) in
if let error = error {
print(error)
return
}
onSuccess()
}
}
Related Topics
How to Increment Exponentially in Swift
Elegant 'Bounded' Methodology in Swift
App Window on Top of All Windows Including Others App Windows
Replace Multiple Words from a String Based on the Values in an Array
How to Take a Substring to the First Index of a Character
Learning Swift: Expressions Are Not Allowed at the Top Level
Swift Sorting Array of Structs by String Double
Swift Issue in Passing Variable Number of Parameters
Raw Value of Enumeration, Default Value of a Class/Structure, What's the Different
How to Handle Two Possible Date Formats
Why Can't I Use 'Type' as the Name of an Enum Embedded in a Struct
Unexpectedly Found Nil While Unwrapping an Optional Value While Reading from Ds with Fromcstring
Is There a Neat Way to Represent a Fraction as an Attributed String
How to Pass Arguments into a Function with Completion Swift
How to Sort an Array of Posts by Their Elements
Where to Place App Delegate Code in App.Swift File
Expanding Uitextview Inside a Stack View with Scrolling Enabled