SDWebImage doesn't work - swift

What am I doing wrong? Everything runs but I don't get the Images, help! Thanks!
import UIKit
import Firebase
import FirebaseDatabase
import SDWebImage
struct postStruct {
let title : String!
let downloadURL : String!
}
class ZeroHomeViewController: UITableViewController {
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!
}
}

Secondly
Replace this line
imageView.sd_setImage(with: URL(string: "downloadUrl"), placeholderImage: UIImage(named: "placeholder.png"))
With this
imageView.sd_setImage(with: URL(string: "www.domain.com/url"), placeholderImage: UIImage(named: "placeholder.png"))
Make sure your edit the url to the image you want

Related

Cannot fetch data from google-cloud-firestore correctly

No problems with fetching Title and Subtitle. Problems are with downloading of images and streaming the video. I really appreciate your help friends. I just want to learn how to implement it correctly and what to use, get data method or listener? Does it need grammatical changes of my code or a pair of code lines?
import UIKit
import AVKit
import AVFoundation
import FirebaseFirestore
import Combine
class ListOfVideoLessonsTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let pinchGesture = UIPinchGestureRecognizer()
private var viewModel = VideosViewModel()
private var cancellable: AnyCancellable?
var player = AVPlayer()
var playerViewController = AVPlayerViewController()
#IBOutlet var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel.fetchData()
self.title = "Video Lessons"
table.delegate = self
table.dataSource = self
cancellable = viewModel.$videos.sink { _ in
DispatchQueue.main.async{
self.table.reloadData()
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("videos count = ", viewModel.videos.count)
return viewModel.videos.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let video = viewModel.videos[indexPath.row]
tableView.tableFooterView = UIView()
//configure cell
cell.textLabel?.text = video.name
cell.detailTextLabel?.text = video.lessonName
cell.accessoryType = .disclosureIndicator
let image = UIImage(data: video.imageData)
cell.imageView?.image = image...
imageName!.withRenderingMode(.alwaysTemplate)
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor(named: "VideoLessonsCellHighlighted")
cell.selectedBackgroundView = backgroundView
cell.textLabel?.font = UIFont(name: "Helvetica-Bold", size: 14)
cell.detailTextLabel?.font = UIFont(name: "Helvetica", size: 12)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
playVideo(at: indexPath)
}
func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.contentView.backgroundColor = UIColor(named: "VideoLessonsCellHighlighted")
cell.textLabel?.highlightedTextColor = UIColor(named: "textHighlighted")
cell.detailTextLabel?.highlightedTextColor = UIColor(named: "textHighlighted")
}
}
func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.contentView.backgroundColor = nil
}
}
func playVideo(at indexPath: IndexPath){
let selectedVideo = viewModel.videos[indexPath.row]
let videoURL = URL(string: selectedVideo.fileURL)
player = AVPlayer(url: videoURL!)
playerViewController.player = player
self.present(playerViewController, animated: true, completion: {
self.playerViewController.player?.play()
})
}
}
This is the VideosViewModel which supposed to download data from firestore database and translate into local file names if I am not mistaken.
import Foundation
import FirebaseFirestore
class VideosViewModel: ObservableObject {
#Published var videos = [Video]()
private var db = Firestore.firestore()
static func downloadImage(withURL url: URL, completion: #escaping (_ _image:UIImage?)->()) {
let dataTask = URLSession.shared.dataTask(with: url) { data, url, error in
var downloadedImage:UIImage?
if let data = data {
downloadedImage = UIImage(data: data)
}
DispatchQueue.main.async {
completion(downloadedImage)
}
}
dataTask.resume()
}
func fetchData() {
db.collection("videos").addSnapshotListener { [self] (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No Documents")
return
}
self.videos = documents.map { (queryDocumentSnapshot) -> Video in
let data = queryDocumentSnapshot.data()
let name = data["name"] as? String ?? ""
let imageName = data["imageName"]as? URL ?? ""
let lessonName = data["lessonName"] as? String ?? ""
let fileURL = data["fileURL"] as? String ?? ""
print(data)
return Video(name: name, imageName: imageName, lessonName: lessonName, fileURL: fileURL)
}
}
}
}
import Foundation
struct Video {
var name: String
var imageName: Data
var lessonName: String
var fileURL: String
}```
[1]: https://i.stack.imgur.com/YIU5O.png

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 to use swiftyJson to get arrayvalue in TableView?

I use swiftyJson to parse data and, but do not know how to parse array.
Here is code.
import UIKit
import Alamofire
import SwiftyJSON
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var json:JSON = JSON.null
var urlSession = URLSession(configuration: .default)
#IBOutlet weak var myTableView: UITableView!
var pokamon = [[String:AnyObject]]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pokamon.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
var dict = pokamon[indexPath.row]
cell.nameLbl.text = dict["name"] as? String
cell.typesLbl.text = dict["types"]?[0] as? String
cell.hpLbl.text = dict["hp"] as? String
cell.subtypeLbl.text = dict["subtype"] as? String
if let image = URL(string: dict["imageUrl"] as! String){
let task = urlSession.downloadTask(with: image) { (url, repsponse, error) in
if error != nil{
print("sorry")
return
}
if let okURL = url{
do{
let downloadImage = UIImage(data: try Data(contentsOf: okURL))
DispatchQueue.main.async {
cell.myImage.image = downloadImage
}
}catch{
print("error")
}
}
}
task.resume()
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 224
}
override func viewDidLoad() {
super.viewDidLoad()
myTableView.delegate = self
myTableView.dataSource = self
Alamofire.request("https://api.pokemontcg.io/v1/cards").responseJSON(completionHandler: { response in
if response.result.isSuccess {
let json:JSON = try! JSON(data: response.data!)
let swiftyJsonVar = JSON(response.result.value!)
if let resData = swiftyJsonVar["cards"].arrayObject{
self.pokamon = resData as! [[String:AnyObject]]
}
if self.pokamon.count > 0{
self.myTableView.reloadData()
}
} else {
print("error: \(response.error)")
}
})
}
}
From cellForRowAt in tableView, it shows "Ambiguous use of 'subscript'" with below code, have no idea how to solve it. The rest like "name", "hp", and "subtype" are no problem!
cell.typesLbl.text = dict["types"]?[0] as? String
Could anyone help me with this error?
Thanks!
The compiler must know the type of any subscripted object. Tell the compiler that you expect an array of strings.
cell.typesLbl.text = (dict["types"] as? [String])?.first
In Swift 3+ all JSON values are Any not AnyObject so declare the array
var pokamon = [[String:Any]]()

Can not display image in table view cell using firebase

I can not display image using firebase in table view cell, I don't know why because my code seems to work, but not there, may anyone help me?
Note: The label Works. I created a custom cell using a cocoa touch class, then I have linked that using the notation to cell as you can see.
import UIKit
import Firebase
class PlacesTableViewController: UIViewController,
UITableViewDataSource, UITableViewDelegate{
let ref = Database.database().reference()
var PlacesRef:DatabaseReference! = nil
var SelectedRef:DatabaseReference! = nil
let storage = Storage.storage()
var postdata:[String] = [String]()
#IBOutlet weak var tableview: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
print("Here Variables")
print("Here translated Names")
PlacesRef = ref.child("Places")
let storageRef = self.storage.reference()
PlacesRef.observe(.value) { (snapshot) in
let postDict = snapshot.value as? [String : AnyObject] ?? [:]
if snapshot.exists() {
for a in ((snapshot.value as AnyObject).allKeys)!{
var now:String = ""
self.postdata.append(a as! String)
DispatchQueue.main.async{
self.tableview.reloadData()
}
}
} else {
print("we don't have that, add it to the DB now")
}
print(self.postdata) //add key to array
}
tableview.delegate = self
tableview.dataSource = self
}
func tableView(_ _tableView: UITableView, numberOfRowsInSection selection: Int) ->Int{
print(postdata)
return postdata.count
}
func tableView( _ tableview: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableview.dequeueReusableCell(withIdentifier: "cell") as! CustomTableViewCell
var image=UIImage()
let StorageRef = storage.reference()
let NationRef = StorageRef.child("Nations/\(postdata[indexPath.row]).jpg")
print("\(postdata[indexPath.row]).jpg")
NationRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
print(error)
} else {
// Data for "images/island.jpg" is returned
image = UIImage(data: data!)!
print("image downloaded!")
}
}
cell.DetailLabel.text = postdata[indexPath.row]
cell.DetailImage.image = image
return cell
}
}
Let's see what happens in
func tableView( _ tableview: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableview.dequeueReusableCell(withIdentifier: "cell") as! CustomTableViewCell
var image=UIImage()
let StorageRef = storage.reference()
let NationRef = StorageRef.child("Nations/\(postdata[indexPath.row]).jpg")
// HERE we starting async web request for image data (tag 1)
NationRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
print(error)
} else {
// HERE we getting image data from async request and storing it in image var (tag 3)
image = UIImage(data: data!)!
print("image downloaded!")
}
}
cell.DetailLabel.text = postdata[indexPath.row]
// HERE we setting UIImage to cell's imageView (tag 2)
cell.DetailImage.image = image
return cell
}
if printing tags we'll get tag 1, tag 2 and tag 3. It means that firstly you create empty uiimage, then set this image to cell's imageView and at last you change image to image from request (image, not cell's imageView)
I think the answer can be - replace image = UIImage(data: data!)! with cell.DetailImage.image = UIImage(data: data!)
and there are many ways to improve this method

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