I'm new to coding and trying to build an iOS App. I am storing images uploaded by users into my firebase storage and then saving the URL as a string ("https//.....). I am able to get a snapshot to show up in project terminal after I use print(snapshot). It prints, snap (profileImageUrl) https://firebasestorage.... How do I use this snapshot to get the ImageView to show the profile picture most recently saved?
import UIKit
import Firebase
import SDWebImage
class EditProfileViewController: UIViewController {
@IBOutlet weak var ProfileImage: UIImageView!
var selectedImage: UIImage?
var ref:DatabaseReference?
var databaseHandle:DatabaseHandle = 0
var postProfileImage = [String]()
let dbref = Database.database().reference()
let uid = Auth.auth().currentUser?.uid
override func viewDidLoad() {
super.viewDidLoad()
self.ref?.child("users").child(Auth.auth().currentUser!.uid).child("profileImageUrl").observe(.value, with: { (snapshot) in
print(snapshot)
})
ProfileImage.layer.borderWidth = 3.0
ProfileImage.layer.masksToBounds = false
ProfileImage.layer.borderColor = UIColor.white.cgColor
ProfileImage.layer.cornerRadius = ProfileImage.frame.size.width / 2
ProfileImage.clipsToBounds = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(EditProfileViewController.handleSelectProfileImageView))
ProfileImage.addGestureRecognizer(tapGesture)
ProfileImage.isUserInteractionEnabled = true
}
@objc func handleSelectProfileImageView() {
let pickerController = UIImagePickerController()
pickerController.delegate = self
present(pickerController, animated: true, completion: nil)
}
@IBAction func Cancel(_ sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
}
let user = Auth.auth().currentUser
let fileData = NSData()
@IBAction func DoneButton(_ sender: UIBarButtonItem) {
guard let imageSelected = self.ProfileImage.image else {
print ("Avatar is nil")
return
}
var dict: Dictionary<String, Any> = [
"profileImageUrl": "",
]
guard let imageData = imageSelected.jpegData(compressionQuality: 0.4) else {
return
}
let storageRef = Storage.storage().reference(forURL: "(I have my storage url here")
let imageName = NSUUID().uuidString
let storageProfileRef = storageRef.child("Profile_Images").child(Auth.auth().currentUser!.uid).child("\(imageName).png")
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
storageProfileRef.putData(imageData, metadata: metadata, completion:
{ (StorageMetadata, error) in
if (error != nil) {
return
}
storageProfileRef.downloadURL { (url, error) in
if let metaImageUrl = url?.absoluteString {
dict["profileImageUrl"] = metaImageUrl
Database.database().reference().child("users").child(Auth.auth().currentUser!.uid).updateChildValues(dict, withCompletionBlock: {
(error, ref) in
if error == nil {
print("Done")
}
}
)
}
}
})
dismiss(animated: true, completion: nil)
}
}
extension EditProfileViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
//print("did Finish Picking Media")
if let image = info[UIImagePickerController.InfoKey(rawValue: "UIImagePickerControllerOriginalImage")] as? UIImage{
selectedImage = image
ProfileImage.image = image
}
dismiss(animated: true, completion: nil)
}
}
I could really use some help!
You can add an extension to UIImageView as below:
extension UIImageView {
func load(url: URL, onLoadCompletion: ((_ isImageLoaded: Bool) -> Void)? = nil) {
self.image = nil
DispatchQueue.global().async { [weak self] in
if let data = try? Data(contentsOf: url) {
if let image = UIImage(data: data) {
DispatchQueue.main.async {
self?.image = image
onLoadCompletion?(true)
}
} else {
onLoadCompletion?(false)
}
} else {
onLoadCompletion?(false)
}
}
}
}
Assuming your image view outlet is something like this:
@IBOutlet weak var imageView: UIImageView!
Below is the usage when adding a loader:
if let url = URL(string: "https://firebase-storage-url") {
// show a loader here if needed
imageView.load(url: url) { (imageLoaded) in
if imageLoaded {
// hide loader
} else {
// show a place holder image
// hide loader
}
}
} else {
// show a default image
}
Below is the usage without any extra work and just loading the image:
if let url = URL(string: "https://firebase-storage-url") {
imageView.load(url: url)
}