How to Use NSData to Get Pictures in Swift - 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!

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
}

TableView white cell after reloadData

I've a problem after load data from firebase, when i call the reload data, the table view populate with new list data but are all white and if I click I can get the data value correctly.
If I use static data all works fine.
Any suggestion? thanks!
private func loadUniversity(url: String) {
let configuration = URLSessionConfiguration.ephemeral
let session = URLSession(configuration: configuration)
let url = URL(string: url)!
let task = session.dataTask(with: url) {
(data, response, error) in
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200, let data = data else {
return
}
do {
let decoder = JSONDecoder()
let university = try decoder.decode([UniversityJSON].self, from: data)
for item in university {
self.universityArray.append(University(name: item.university_name.trim()))
}
let queue = OperationQueue.main
queue.addOperation {
self.currentUniversityArray = self.universityArray
print(self.currentUniversityArray)
self.table.reloadData()
}
} catch {
print("Error info: \(error)")
}
}
task.resume()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? UniversityCell else {
return UITableViewCell()
}
cell.name.text = currentUniversityArray[indexPath.row].name
return cell
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? UniversityCell else {
return UITableViewCell()
}
cell.name.text = currentUniversityArray[indexPath.row].name
// Put this background Color
cell.backgroundColor = .clear
return cell
}

Downloading profile image string from firebase database to an uiimage

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.

Swift, Stop Images from loading in table View

Here I load my images, I want to stop the images from loading when I click on the path. How can this be done? I tried setting the URL to nil but that didn't work.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as? CustomCell
let pintrestsUrl = pintrest[indexPath.row].urls?.thumb
Library().parseImages(ImagesUrlArrayPath: pintrestsUrl!, completion: { (image) -> Void in
if let imageFromCache = imageCache.object(forKey: pintrestsUrl as AnyObject ) as? UIImage {
cell?.ImageView.image = imageFromCache
}
})
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// stop images from loading
}
EDIT -- added ParseImages Function
func parseImages(ImagesUrlArrayPath: String, completion: #escaping (UIImage)-> Void) {
if let imageFromCache = imageCache.object(forKey: ImagesUrlArrayPath as AnyObject ) as? UIImage {
completion(imageFromCache)
}
else
{
if let imageURL = URL(string: (ImagesUrlArrayPath)){
DispatchQueue.global().async{
let data = try? Data(contentsOf: imageURL)
if let data = data{
let imageToCache = UIImage(data: data)
// let image = imageToCache
DispatchQueue.main.async {
imageCache.setObject(imageToCache!, forKey: ImagesUrlArrayPath as AnyObject)
completion(imageToCache!)
print("sucess")
//cell?.videoImageView.image = image //?.resizeImage(targetSize: size)
}
}
}
}
}
}
Solved this awhile back
You have to set the images to nil before loading new images on them

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!
}