Downloading profile image string from firebase database to an uiimage - swift

User upload image to firebase storage and the url string is added to the firebase database,
How can I take the string in the firebase database and convert it to uiimage to use it as an image ?
The string returned from database is like this:
https://firebasestorage.googleapis.com/v0/b/ichatmessage.appspot.com/o/YNoodTnOSGXl6HkPoqhOPAopb8v1?alt=media&token=738771a5-53e3-46c2-b508-ad5cfa03e74e
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! NewMessageCell
let user = users[indexPath.row]
cell.textLabel?.text = user.username
cell.detailTextLabel?.text = user.email
let currentID = Auth.auth().currentUser?.uid
let databaseRef = Database.database().reference().child("users").child(currentID!)
databaseRef.observe(.value) { (data) in
let dictinoray = data.value as? [String: AnyObject]
let profileImage = dictinoray!["profileimage"] as! String
cell.imageView?.image = profileImage.toImage()
print(profileImage)
}
return cell
}
extention
extension String {
func toImage() -> UIImage? {
if let data = Data(base64Encoded: self, options: .ignoreUnknownCharacters){
return UIImage(data: data)
}
return nil
}
}

I used other way by mapping and using storage downloadurl and it worked
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! NewMessageCell
let user = users[indexPath.row]
cell.textLabel?.text = user.username
cell.detailTextLabel?.text = user.email
let storageref = Storage.storage().reference().child(user.userid)
storageref.downloadURL { (imgurl, er) in
let imagedata = try? Data.init(contentsOf: imgurl!)
cell.imageView?.layer.cornerRadius = (cell.imageView?.frame.size.width)!/2
cell.imageView?.image = UIImage.init(data: imagedata!)
}

Another option would be to load and cache the image through Kingfisher. It's how I would usually load images within a tableView that's from an API.
import Kingfisher above your class.
Then in your cellForRowAtIndexPath, set the image with Kingfisher.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellID") as! NewMessageCell
let user = users[indexPath.row]
cell.textLabel?.text = user.username
cell.detailTextLabel?.text = user.email
let currentID = Auth.auth().currentUser?.uid
let databaseRef = Database.database().reference().child("users").child(currentID!)
databaseRef.observe(.value) { (data) in
let dictinoray = data.value as? [String: AnyObject]
let profileImage = dictinoray!["profileimage"] as! String
cell.imageView?.kf.setImage(with: URL(string: profileImage))
}
return cell
}
Not sure if you were looking for an alternative but that's another way to do it.

Related

My Images are not loading in the correct order

I have a tableview called (events) where i am pulling images from firebase and loading them, The idea is to post events and add flyer images with the event post. it works perfectly but when i close the app and reopen the images are not in the correct order and some images are on the wrong event. Any help will be greatly appreciated i am very new to coding.
eventsDatabaseHandle = eventsRef?.child("Church Events").observe(.childAdded, with: { (snaphot) in
let eventPost = snaphot.value as! [String: Any]
var event = Event(title: eventPost["eventtitle"] as! String,
timestamp: eventPost["eventdate"] as! String,
location: eventPost["eventlocation"] as! String,
image: nil)
let task = URLSession.shared.dataTask(with: URL(string: eventPost["ImageUrl"] as! String)!) { data, _, error in
if let image: UIImage = UIImage(data: data!) {
event.image = image
DispatchQueue.main.async {
self.events.append(event)
self.tableView.reloadData()
}
}
}
task.resume()
})
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return events.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "events", for: indexPath) as! EventsTableViewCell
let event = events[indexPath.row]
cell.flyerImages.image = event.image
cell.eventTitle.text = event.title
cell.eventDate.text = event.timestamp
cell.eventLocation.text = event.location
Edit your Event object to take imageURL instead of UIImage, and try the following after download this lightweight library which handles downloading and caching your images
eventsDatabaseHandle = eventsRef?.child("Church Events").observe(.childAdded, with: { (snaphot) in
let eventPost = snaphot.value as! [String: Any]
var event = Event(title: eventPost["eventtitle"] as! String,
timestamp: eventPost["eventdate"] as! String,
location: eventPost["eventlocation"] as! String,
imageURL: eventPost["ImageUrl"])
self.events.append(event)
})
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "events", for: indexPath) as! EventsTableViewCell
let event = events[indexPath.row]
if let imgURL = URL(string:event.imageURL)
{
cell.flyerImages.kf.setImage(with:imgURL)
}
cell.eventTitle.text = event.title
cell.eventDate.text = event.timestamp
cell.eventLocation.text = event.location
}

Filtering data snapshot Swift Firebase

I'm trying to return data from the database which I've done successfully. The problem is I don't want all data to be featured, but only the ones with the current UID which is stored in the JSON tree.
Here is my JSON tree, there is only one current UID but there will be many.
user_posts-
LDLc60j71FBvJGeYn5i
description: "Write here"
photoUrl: "https://firebasestorage.googleapis.com/v0/b/blo..."
uid: "zQRxvM3cwzQMewUtVamk8JQrEFJ3"
Here is my current code returning all data from database folder:
var posts2 = [user_posts]()
func loadPosts(){
Database.database().reference().child("user_posts").observe(.childAdded) {(snapshot: DataSnapshot) in
if let dict = snapshot.value as? [String: Any] {
let descriptionText = dict["description"] as! String
let photoUrlString = dict["photoUrl"] as! String
let post = user_posts(descriptionText: descriptionText, photoUrlString: photoUrlString)
self.posts2.append(post)
self.myPageTableView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboardWhenTappedAround()
myPageTableView.dataSource = self
myPageTableView.delegate = self
loadPosts()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return posts2.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier:"myPageCell", for: indexPath)
as! myPageTableViewCell
cell.myPageDescription?.text = posts2[indexPath.row].description
let photoUrl = posts2[indexPath.row].photoUrl
let url = URL(string: photoUrl)
cell.myPageImage.sd_setImage(with: url, placeholderImage: nil)
return cell
}
}
To load only the posts for a specific user, you'll want to use a Firebase query:
let uid = Auth.auth().currentUser.uid
let posts = Database.database().reference().child("user_posts")
let query = posts.queryOrdered(byChild: "").queryEqual(toValue: uid)
query.observe(.childAdded) {(snapshot: DataSnapshot) in
...
Also see the Firebase documentation on ordering and filtering data.

Image are not showing in table View

i am trying to get a list of items from mysql and display them in the app.
names appear but the image and price dose not.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = tableView.dequeueReusableCell(withIdentifier: "BasicCell", for: indexPath)
var cell:UITableViewCell? =
tableView.dequeueReusableCell(withIdentifier: "BasicCell", for: indexPath)
if (cell == nil)
{
cell = UITableViewCell(style: UITableViewCellStyle.subtitle,
reuseIdentifier: "BasicCell")
}
// Get the location to be shown
let item: Location = locations[indexPath.row]
// let price=locations[indexPath.row].price
let price=(item.price as NSString).floatValue
let cellPrice = String(format: "%.2f",price)
let serverurl=NSURL(string: "https://myoscapp.com/boot/images/")
let imageaddress = locations[indexPath.row].image
let imageURL = NSURL.init(string: imageaddress, relativeTo: serverurl! as URL)
cell?.textLabel?.text=locations[indexPath.row].name
cell?.detailTextLabel?.text = cellPrice
cell?.imageView?.sd_setImage(with: imageURL! as URL )
cell?.setNeedsLayout() //invalidate current layout
cell?.layoutIfNeeded() //update immediately
return cell!
}
i got everything to work like this. i don't know if for:indexPath is going to have an effect but i don't see anything
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = tableView.dequeueReusableCell(withIdentifier: "BasicCell", for: indexPath)
let cell = UITableViewCell(style: UITableViewCellStyle.subtitle,
reuseIdentifier: "BasicCell")
// Get the location to be shown
let item: Location = locations[indexPath.row]
// let price=locations[indexPath.row].price
let price=(item.price as NSString).floatValue
let cellPrice = String(format: "%.2f",price)
let serverurl=NSURL(string: "https://myoscapp.com/boot/images/")
let imageaddress = locations[indexPath.row].image
let imageURL = NSURL.init(string: imageaddress, relativeTo: serverurl! as URL)
cell.textLabel?.text=locations[indexPath.row].name
cell.detailTextLabel?.text = cellPrice
cell.imageView?.sd_setImage(with: imageURL! as URL )
cell.setNeedsLayout() //invalidate current layout
cell.layoutIfNeeded() //update immediately
return cell
}

How do I use SDImageView to download URL within a TableViewCell?

I am trying to use the SDImageView Cocoapod with a table view to retrieve a URL from a database and turning it into a viewable image. When I use the code bellow I don't get images in return, what is wrong with my code? Thanks!
var posts = [postStruct]()
override func viewDidLoad() {
super.viewDidLoad()
let ref = Database.database().reference().child("Posts")
ref.observeSingleEvent(of: .value, with: { snapshot in
print(snapshot.childrenCount)
for rest in snapshot.children.allObjects as! [DataSnapshot] {
guard let value = rest.value as? Dictionary<String,Any> else { continue }
guard let title = value["Title"] as? String else { continue }
guard let downloadURL = value["Download URL"] as? String else { continue }
let post = postStruct(title: title, downloadURL: downloadURL)
self.posts.append(post)
}
self.posts = self.posts.reversed(); self.tableView.reloadData()
})
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
let imageView = cell?.viewWithTag(200) as! UIImageView
imageView.sd_setImage(with: URL(string: "downloadURL"), placeholderImage: UIImage(named: "placeholder.png"))
let label1 = cell?.viewWithTag(1) as! UILabel
label1.text = posts[indexPath.row].title
return cell!
}
You need to change SDWebimage syntax as ->
var posts = [postStruct]()
var downloadURL : String = ""
override func viewDidLoad() {
super.viewDidLoad()
let ref = Database.database().reference().child("Posts")
ref.observeSingleEvent(of: .value, with: { snapshot in
print(snapshot.childrenCount)
for rest in snapshot.children.allObjects as! [DataSnapshot] {
guard let value = rest.value as? Dictionary<String,Any> else { continue }
guard let title = value["Title"] as? String else { continue }
downloadURL = value["Download URL"] as? String ?? ""
let post = postStruct(title: title, downloadURL: downloadURL)
self.posts.append(post)
}
self.posts = self.posts.reversed(); self.tableView.reloadData()
})
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
let imageView = cell?.viewWithTag(200) as! UIImageView
imageView.sd_setImage(with: URL(string: downloadURL), placeholderImage: UIImage(named: "placeholder.png"))
let label1 = cell?.viewWithTag(1) as! UILabel
label1.text = posts[indexPath.row].title
return cell!
}
Where downloadURL is url String.
You first need to pick the postStruct from the array and then the downloadURL. Change your override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell method with this.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
let imageView = cell?.viewWithTag(200) as! UIImageView
let post = self.posts[indexPath.row];
imageView.sd_setImage(with: URL(string: post.downloadURL), placeholderImage: UIImage(named: "placeholder"))
let label1 = cell?.viewWithTag(1) as! UILabel
label1.text = posts[indexPath.row].title
return cell!
}

How to Use NSData to Get Pictures in Swift

This is my code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "news", for: indexPath)
let lebel = cell.viewWithTag(1) as! UILabel
let lebel1 = cell.viewWithTag(2) as! UILabel
lebel.text = self.titlename[indexPath.row]
lebel1.text = self.content[indexPath.row]
var image: UIImage?
if let imageURL = URL(string:self.picture[indexPath.row] ) {
do {
let imageData = try Data(contentsOf:imageURL as URL)
image = UIImage(data:imageData as Data)
} catch {
print("error")
}
}
if image != nil {
cell.imageView?.image = image
}else{
cell.imageView?.image = nil
//cell.imageView?.image = UIImage(named: "failed")
}
return cell
}
self.picture is a String array. When I make a network request, the URL I want to connect to is https://localhost:8443/news/p0.jpg. I get this error:
2017-01-11 10:11:28.888 pro[19800:2397129] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)error
But I have been using Alamofire to connect to https in other places has been very successful. What is wrong with it?
OK,I try to use URL and Data,But this has nothing to do with the error
OK,it is done! because I use Alamofire to manager the connection, so I must use alamofire to fetch the image data. Rather than the original method!!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "news", for: indexPath)
let lebel = cell.viewWithTag(1) as! UILabel
let lebel1 = cell.viewWithTag(2) as! UILabel
let pict = cell.viewWithTag(3) as! UIImageView
lebel.text = self.titlename[indexPath.row]
lebel1.text = self.content[indexPath.row]
if let imageURL = URL(string:self.picture[indexPath.row]) {
Alamofire.request(imageURL, method: .get).responseData { response in
guard let data = response.result.value else {
pict.image = nil
//cell.imageView?.image = UIImage(named: "failed")
return
}
pict.image = UIImage(data: data)
}
}
return cell
}
But so much thanks!