I had the difficulty with mixing up of the pictures as a result of reuse of cells. This I solved (no less than I assumed I solved) by doing the examine contained in the cell, for the id of the consumer, in order that the id property matches with the picture url being fetched from server. Nevertheless, even with this, my photographs are nonetheless being combined up between cells. That is my code within the customized cell class:
import UIKit
class AllUsersListCell: UITableViewCell {
var preImageRequestIdentity: String = ""
var imgUrl: String? {
didSet {
loadImageFromUrl()
}
}
let imgIcon: UIImageView = {
let ic = UIImageView()
ic.contentMode = .scaleAspectFill
ic.layer.cornerRadius = 5.0
ic.clipsToBounds = true
ic.tintColor = .lightGray
ic.backgroundColor = APP_YELLOW_COLOR
return ic
}()
let lblCaption: UILabel = {
let ic = UILabel()
ic.font = .appFontWithSize(measurement: 22.0)
return ic
}()
override init(type: UITableViewCell.CellStyle, reuseIdentifier: String?) {
tremendous.init(type: type, reuseIdentifier: reuseIdentifier)
backgroundColor = .clear
selectionStyle = .none
addSubview(imgIcon)
imgIcon.translatesAutoresizingMaskIntoConstraints = false
imgIcon.leftAnchor.constraint(equalTo: safeAreaLayoutGuide.leftAnchor, fixed: 24.0).isActive = true
imgIcon.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
imgIcon.widthAnchor.constraint(equalToConstant: 34.0).isActive = true
imgIcon.heightAnchor.constraint(equalTo: imgIcon.widthAnchor).isActive = true
addSubview(lblCaption)
lblCaption.translatesAutoresizingMaskIntoConstraints = false
lblCaption.leftAnchor.constraint(equalTo: imgIcon.rightAnchor, fixed: 16.0).isActive = true
lblCaption.centerYAnchor.constraint(equalTo: imgIcon.centerYAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been carried out")
}
func loadImageFromUrl() {
guard imgUrl != "" else {
return
}
guard let imageUrl = imgUrl, let url = URL(string: imageUrl) else {
print("Invalid URL string")
return
}
URLSession.shared.dataTask(with: url) { information, response, error in
if let error = error {
print("Didn't load picture: (error.localizedDescription)")
return
}
guard let information = information, let picture = UIImage(information: information) else {
print("Invalid picture information")
return
}
DispatchQueue.predominant.async {
self.imgIcon.picture = picture
}
}.resume()
}
func callProfileImageApi(id: String) {
self.preImageRequestIdentity = id
self.imgUrl = ""
Api.sharedInstance.httpGet(url: getUserProfileImageUrl(forUser: id)) { (response, error) in
guard let r = response else {
print("response fell by means of")
return
}
if r.worth(forKey: "image_url") as! String == "" {
self.imgUrl = ""
} else {
let iu = r.worth(forKey: "image_url") as! String
let fullImageUrlString = "(getBaseUrl())(iu)"
if self.preImageRequestIdentity == id {
self.imgUrl = fullImageUrlString
} else {
self.imgUrl = ""
self.callProfileImageApi(id: id)
}
}
}
}
}
and that is the code within the precise web page which is the desk view delegate:
//
// AllUsersChatListVC.swift
//
//
//
import UIKit
import CloudKit
import TwilioConversationsClient
import SwiftUI
class AllUsersChatListVC: GosViewController {
// Tapped different consumer's id
var otherUserIdentity: String!
var tableView: UITableView!
var pullRefresher:UIRefreshControl = UIRefreshControl()// Added for desk view pull to referesh in order that we do not have to kill and begin once more the app
var arrTwillioUsers = [User]()
var aLabel: UILabel!
var isInitiallyLoading = false
override func viewDidLoad() {
tremendous.viewDidLoad()
let defaults = UserDefaults.commonplace
if isUserLoggedIn() {
if let id = defaults.string(forKey: kUserIdentity) {
currentUserIdentity = id
} else {
currentUserIdentity = "UNKNOWN"
}
}
self.pullRefresher.tintColor = .black
self.pullRefresher.shadowColorOverAll = .black
view.backgroundColor = .white
configureNavBar()
configureSpacingLabel()
configureUserTableView()
self.showLoading()
self.isInitiallyLoading = true
callGetAllUsersAPI()
}
override func viewWillAppear(_ animated: Bool) {
tremendous.viewWillAppear(animated)
navigationController?.navigationBar.tintColor = APP_YELLOW_COLOR // DEV: see if this causes coloration points on dragging the display up/down on all chat web page
navigationController?.hidesBarsOnSwipe = false
navigationController?.hidesBarsOnTap = false
navigationController?.hidesBarsWhenKeyboardAppears = false
navigationController?.hidesBarsWhenVerticallyCompact = false
navigationController?.navigationBar.barStyle = .default
navigationController?.navigationBar.isHidden = false
navigationItem.setHidesBackButton(true, animated: true)
}
override func viewWillDisappear(_ animated: Bool) {
tremendous.viewWillDisappear(animated)
}
// Label that serves so the colour does not change on the nav bar when dragged down
func configureSpacingLabel() {
aLabel = UILabel(body: CGRect(x: 0, y: 0, width: 200, peak: 21))
aLabel.heart = CGPoint(x: 100, y: 10)
aLabel.textAlignment = .left
aLabel.textual content = "Spacing label"
view.addSubview(aLabel)
}
func configureUserTableView() {
tableView = UITableView()
tableView.delegate = self
tableView.dataSource = self
tableView.register(AllUsersListCell.self, forCellReuseIdentifier: reuseId)
tableView.contentInset = .init(prime: 16.0, left: 0, backside: 0, proper: 0)
tableView.backgroundColor = .white
view.addSubview(tableView)
tableView.tableFooterView = UIView(body: .zero)
tableView.layer.backgroundColor = UIColor.white.cgColor
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
// pull to refresh added on tableview
self.pullRefresher.addTarget(self, motion: #selector(self.onSwipeRefresh), for: .valueChanged)
self.tableView.refreshControl = self.pullRefresher
self.pullRefresher.tintColor = .black
}
// swipe lister of pull to refresh
@objc func onSwipeRefresh() {
print("in inSwipeRefresh")
self.callGetAllUsersAPI()
}
func configureNavBar() {
let topLabel = UILabel(body: CGRect(x: 0, y: 0, width: 200, peak: 21))
topLabel.textAlignment = .heart
topLabel.textual content = currentUserIdentity
topLabel.font = UIFont(title: GOS_FONT_NAME, measurement: vcTitleSize)
navigationItem.titleView = topLabel
self.navigationController?.setStatusBar(backgroundColor: APP_YELLOW_COLOR)
}
func callGetAllUsersAPI() {
if offline {
let consumer : Person = Person()
consumer.id = "fadil"
arrTwillioUsers.append(consumer)
let user2 : Person = Person()
user2.id = "Memara"
arrTwillioUsers.append(user2)
self.tableView.reloadData()
self.pullRefresher.endRefreshing()
self.hideLoading()
} else {
Api.sharedInstance.httpGet(url: WS_URL(url: GetAllUsersAPI)) { [weak self] (response, error) in
self?.pullRefresher.endRefreshing()
if self?.isInitiallyLoading ?? true {
self?.hideLoading()
self?.isInitiallyLoading = false
}
if (error == nil) {
self?.manageUserResponse(dict: response)
} else {
self!.showAlert(title: "Error", message: error?.area)
}
}
}
}
func manageUserResponse(dict : NSDictionary?) {
guard let arr = dict?.worth(forKey: param_users) else { return }
let arrUsers = arr as! [Any]
arrTwillioUsers.removeAll()
if arrUsers.rely > 0 {
for userDictionary in arrUsers {
let consumer : Person = Person.init(dictionary: userDictionary as! NSDictionary)!
arrTwillioUsers.append(consumer)
}
}
arrTwillioUsers = arrTwillioUsers.filter({$0.id != currentUserIdentity})
arrTwillioUsers = arrTwillioUsers.sorted(by: { $0.id ?? "" < $1.id ?? ""})
self.tableView.reloadData()
}
func handleClick(otherUser: String) {
print("in handleClick")
self.otherUserIdentity = otherUser
if offline {
prepareAndPushChatPage(cur: self.currentUserIdentity, oth: self.otherUserIdentity)
} else {
self.showLoading()
if isTokenExpired() {
ConversationsManager.shared.refreshAccessToken() {
self.prepareAndPushChatPage(cur: self.currentUserIdentity, oth: self.otherUserIdentity)
}
} else {
prepareAndPushChatPage(cur: self.currentUserIdentity, oth: self.otherUserIdentity)
}
}
}
func prepareAndPushChatPage(cur: String, oth: String) {
ConversationsManager.shared.initializeConversationManager(token: getToken(), conversationDelegate: self) {
self.loadChatPage(cur: self.currentUserIdentity, oth: self.otherUserIdentity)
}
}
func loadChatPage(cur: String, oth: String) -> Void {
guard oth != "" && cur != "" else {
return
}
let cvc = ChatVC()
cvc.currentUserIdentity = cur
cvc.currentChatPartnerIdentity = oth
// Forestall reopening for identical consumer
//openChatWithUser = ""
DispatchQueue.predominant.async {
self.navigationController?.pushViewController(cvc, animated: true)
self.hideLoading()
}
self.chatVC = cvc
}
}
// MARK: - TableView Delegate
extension AllUsersChatListVC: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection part: Int) -> Int {
return arrTwillioUsers.rely
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.handleClick(otherUser: arrTwillioUsers[indexPath.row].id!)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseId, for: indexPath) as! AllUsersListCell
let objUser = arrTwillioUsers[indexPath.row]
cell.lblCaption.textual content = objUser.id // precise textual content for a consumer, for a row within the customers chat checklist
cell.lblCaption.font = UIFont(title: GOS_FONT_NAME, measurement: 22)
cell.callProfileImageApi(id: objUser.id!)
tableView.rowHeight = 60
return cell
}
}
what am I doing fallacious?