Post

Replies

Boosts

Views

Activity

Reply to Swift user online status updates but it repeats on cells that is not supposed to
OK, I had to think about this one more time and i finally got it working 100%. Aside from the call to get all the user documents, I was making another call at the same time to the collection that was storing the values for isOnline. I added isOnline to the members model and a separate snapshot listener to monitor the changes to that key. Now everything is working 100%. Hope this helps anyone. I have updated my code: Service Class **This function is to update the user's presence when online or not and it's called inside SceneDelegate **  static func isUserOnline(bool: Bool) {     guard let currentUID = Auth.auth().currentUser?.uid else { return }           if !currentUID.isEmpty {       let dictionary = [USER_IS_ONLINE: bool as Any,              USER_LASTEST_ONLINE: Date().timeIntervalSince1970 as Any]               USERS_COLLECTION.document(currentUID).getDocument { (document, error) in         if let error = error {           print("Error..\(error.localizedDescription)")         } else {           if document?.exists == true {             USERS_COLLECTION.document(currentUID).updateData(dictionary)           } else {             USERS_COLLECTION.document(currentUID).updateData(dictionary)           }}}}} **SceneDelegate** func sceneDidDisconnect(_ scene: UIScene) {     Service.isUserOnline(bool: false)   }   func sceneDidBecomeActive(_ scene: UIScene) {     Service.isUserOnline(bool: true)   }   func sceneWillResignActive(_ scene: UIScene) {     Service.isUserOnline(bool: false)   }   func sceneDidEnterBackground(_ scene: UIScene) {     Service.isUserOnline(bool: false)   } **This function is to monitor the user activity**       static func checkUserOnlineStatus(with userId: String, completion: @escaping(Bool) -> Void) {     let query = USERS_COLLECTION.document(userId)           query.getDocument { (document, error) in       if let document = document, document.exists {         let isOnline = document.get(USER_IS_ONLINE) as? Bool ?? false         completion(isOnline)       }     }     query.addSnapshotListener { (document, error) in       if let document = document, document.exists {         let isOnline = document.get(USER_IS_ONLINE) as? Bool ?? false         completion(isOnline)       }}} Calling the function inside the cell class func configureHomeFeedCell(member: Member) {  Service.checkUserOnlineStatus(with: member.documentId) { isOnline in       self.onlineViewStatus.backgroundColor = isOnline == true ? .green : .red     } }
Topic: Programming Languages SubTopic: Swift Tags:
Jan ’23
Reply to Swift user online status updates but it repeats on cells that is not supposed to
Thank you for the last suggestion, I ended moving the function from the cell class to the view controller and called it inside cellForRowAt, so far, it's working as expected. Here is the updated code: func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {     let hCell = homeFeedTableView.dequeueReusableCell(withIdentifier: "HomeFeedCell", for: indexPath) as! HomeFeedCell           hCell.selectionStyle = .none     hCell.backgroundColor = UIColor.white           if !members.isEmpty {       hCell.configureHomeFeedCell(member: self.members[indexPath.row])       checkUserOnlineStatus(with: members[indexPath.row].documentId) { isOnline in         hCell.onlineViewStatus.backgroundColor = isOnline == true ? .green : .red       }     }     return hCell   }           func checkUserOnlineStatus(with userId: String, completion: @escaping(Bool) -> Void) {     let query = USERS_COLLECTION.document(userId).collection(IS_ONLINE)     query.getDocuments { (snapshot, error) in       if let error = error {         print("ERROR..\(error.localizedDescription)")       } else {         snapshot?.documents.forEach({ diff in           let isOnline = diff.get(USER_IS_ONLINE) as? Bool           completion(isOnline!)         })}}       query.addSnapshotListener { (snapshot, error) in         snapshot?.documentChanges.forEach { diff in           let isOnline = diff.document.get(USER_IS_ONLINE) as? Bool           if (diff.type == .modified) {             completion(isOnline!)           }}}   }
Topic: Programming Languages SubTopic: Swift Tags:
Jan ’23
Reply to UITableView reload not working
You were correct, after delaying the dismissal of the view controllers by 2 seconds, the table view is refreshed with no issues. To transition back to the MemberListVC I was using "unWind" but the problem there is that as soon as you press the button, it jumps back to the initial VC and there was no time for the async call to finish. So what I end up doing is adding the 2 seconds delay (it shows a loader while is running) and calling the returnToInitialVC() function, this function removes the 2 views from the stack. Thank you for your time! DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {         self.returnToInitialVC()         self.showLoader(false)       } func returnToInitialVC() {     let viewControllers: [UIViewController] = self.navigationController!.viewControllers as [UIViewController]     self.navigationController!.popToViewController(viewControllers[viewControllers.count - 3], animated: true)   }
Topic: UI Frameworks SubTopic: UIKit Tags:
Oct ’21
Reply to UITableView reload not working
User is blocked in alert action, once done that MemberVC is dismissed and app goes to MemberListVC. Let's say in MemberListVC you have 3 users, you open one of the profiles with MemberVC and then you block the user. When the app goes back to the MemberListVC, there should be 2 users only. I'm going to do a test delaying the dismissal to MemberListVC, let's see if that gives time for the async call to finish and the table view reloads properly.
Topic: UI Frameworks SubTopic: UIKit Tags:
Oct ’21
Reply to UITableView reload not working
The goal of that statement is to remove the user that is logged in when I'm filtering the array. As mentioned, that section works properly, the issue I'm having is reloading/refreshing the table view when i go back to MemberListVC. Is viewDidAppear or viewWillAppear OK to use to reload/refresh the table view?
Topic: UI Frameworks SubTopic: UIKit Tags:
Oct ’21
Reply to UITableView reload not working
To load the array inside ViewDidLoad in calling this function "fetchUsers()". Inside this block lastDocument is included. And userDefaults is loaded in the MemberVC right after the user block is called. func fetchUsers() {     if lastDocument == nil {       let query = MATCH_INFO_COLLECTION.document(currentUID!)         .collection("info").order(by: MATCH_TIMESTAMP, descending: false)               query.limit(to: 10).getDocuments { (snapshot, error) in                        self.filterUsersThatWereBlocked { blockedUsers in                                   guard let last = snapshot?.documents.last else { return }                 guard let snap = snapshot else { return }                 snap.documents.forEach({ document in                                       let data = document.data()                   let memberId = data[DOCUMENT_ID] as? String ?? ""                   let memberAge = data[AGE] as? Int ?? 0                   let memberName = data[FIRST_NAME] as? String ?? ""                   let memberImageUrl = data[PROFILE_IMAGE_URL] as? String ?? ""                   let memberCurrentCity = data[CURRENT_CITY] as? String ?? ""                   let timestamp = data[TIMESTAMP] as? Double ?? 0.0                                       let matches = Match(memberId: memberId, memberAge: memberAge ,memberName: memberName, memberImageUrl: memberImageUrl, memberCurrentCity: memberCurrentCity, timestamp: Date(timeIntervalSince1970: timestamp))                                       guard matches.memberId != Auth.auth().currentUser?.uid else { return }                                       guard blockedUsers[matches.memberId] == nil else { return }                                       self.match.append(matches)                                                           self.matchedMessagesTV.reloadData()                 })                 self.lastDocument = last               }}     } else {       matchedMessagesTV.tableFooterView = createSpinnerFooter()       let query = MATCH_INFO_COLLECTION.document(currentUID!)         .collection("info").order(by: MATCH_TIMESTAMP, descending: false)               query.start(afterDocument: lastDocument!)         .limit(to: 10).getDocuments { (snapshot, error) in                         self.filterUsersThatWereBlocked { blockedUsers in                   DispatchQueue.main.async {                     self.matchedMessagesTV.tableFooterView = nil                   }                   guard let last = snapshot?.documents.last else { return }                   guard let snap = snapshot else { return }                                       snap.documents.forEach({ document in                                           let data = document.data()                     let memberId = data[DOCUMENT_ID] as? String ?? ""                     let memberAge = data[AGE] as? Int ?? 0                     let memberName = data[FIRST_NAME] as? String ?? ""                     let memberImageUrl = data[PROFILE_IMAGE_URL] as? String ?? ""                     let memberCurrentCity = data[CURRENT_CITY] as? String ?? ""                     let timestamp = data[TIMESTAMP] as? Double ?? 0.0                                           let matches = Match(memberId: memberId, memberAge: memberAge ,memberName: memberName, memberImageUrl: memberImageUrl, memberCurrentCity: memberCurrentCity, timestamp: Date(timeIntervalSince1970: timestamp))                                           guard matches.memberId != Auth.auth().currentUser?.uid else { return }                                           guard blockedUsers[matches.memberId] == nil else { return }                                           self.match.append(matches)                                                           self.matchedMessagesTV.reloadData()                   })                   self.lastDocument = last                 }}}   }
Topic: UI Frameworks SubTopic: UIKit Tags:
Oct ’21
Reply to UITableView reload not working
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {          return match.count   } class Match {       let memberId: String   let memberAge: Int   let memberName: String   let memberImageUrl: String   let memberCurrentCity: String   let timestamp: Date!       init(memberId: String, memberAge: Int, memberName: String, memberImageUrl: String, memberCurrentCity: String, timestamp: Date) {           self.memberId = memberId     self.memberAge = memberAge     self.memberName = memberName     self.memberImageUrl = memberImageUrl     self.memberCurrentCity = memberCurrentCity     self.timestamp = timestamp   } } and these are the properties in the main VC: var match = [Match]()   var lastDocument: DocumentSnapshot? = nil   let userDefaults = UserDefaults.standard
Topic: UI Frameworks SubTopic: UIKit Tags:
Oct ’21
Reply to UITableView reload not working
Per your request: func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {     let tvCell = matchedMessagesTV.dequeueReusableCell(withIdentifier: "MatchedMessagesCell", for: indexPath) as! MatchedMessagesCell     tvCell.configureMatchedMessagesCell(match: match[indexPath.row])           tvCell.selectionStyle = .none     tvCell.backgroundColor = .beige           tvCell.profileImageBlur.isHidden = true     tvCell.profileNameBlur.isHidden = true     tvCell.profileCityBlur.isHidden = true     tvCell.timeStampBlur.isHidden = true     tvCell.matchAvailableLbl.isHidden = true           if indexPath.row >= 2 {       tvCell.profileImageBlur.isHidden = false       tvCell.profileNameBlur.isHidden = false       tvCell.profileCityBlur.isHidden = false       tvCell.timeStampBlur.isHidden = false       tvCell.matchAvailableLbl.isHidden = false     }     return tvCell   } and here is the cell class: class MatchedMessagesCell: UITableViewCell {       @IBOutlet weak var profileImage: UIImageView!   @IBOutlet weak var profileNameLbl: UILabel!   @IBOutlet weak var profileCityLbl: UILabel!   @IBOutlet weak var timeStampLbl: UILabel!   @IBOutlet weak var profileImageBlur: UIVisualEffectView!   @IBOutlet weak var profileCityBlur: UIVisualEffectView!   @IBOutlet weak var profileNameBlur: UIVisualEffectView!   @IBOutlet weak var timeStampBlur: UIVisualEffectView!       func configureMatchedMessagesCell(match: Match) {           profileImage.loadImage(with: match.memberImageUrl)     profileNameLbl.text = match.memberName + "(" + "\(match.memberAge)" + ")"     profileCityLbl.text = match.memberCurrentCity     timeStampLbl.text = match.timestamp.timeAgoToDisplay()   } }
Topic: UI Frameworks SubTopic: UIKit Tags:
Oct ’21
Reply to UITableView refresh issue
func fetchGlimpseData() {       if lastDocument == nil {         GLIMPSE_ALL_USERS_DATA.order(by: TIMESTAMP, descending: true).limit(to: 3)           .getDocuments { [self] (snapshot, error) in           guard let last = snapshot?.documents.last else { return }             for dictionary in snapshot!.documents {                            let name = dictionary[FIRST_NAME] as? String ?? ""             let age = dictionary[AGE] as? String ?? ""             let city = dictionary[CURRENT_CITY] as? String ?? ""             let profileImageURL = dictionary[PROFILE_IMAGE_URL] as? String ?? ""             let glimpseCaption = dictionary[GLIMPSE_CAPTION] as? String ?? ""             let glimpseURL = dictionary[GLIMPSE_IMAGE_URL] as? String ?? ""             let timestamp = dictionary[TIMESTAMP] as? Double ?? 0.0             let documentID = dictionary.documentID                           let glimpseInfo = Glimpse(name: name, age: age, city: city, profileImageURL: profileImageURL, glimpseCaption: glimpseCaption, glimpseURL: glimpseURL, timestamp: Date(timeIntervalSince1970: timestamp), documentID: documentID)                               self.glimpse.append(glimpseInfo)               self.glimpseTableView.reloadData()             }           self.lastDocument = last         }       } else {         glimpseTableView.tableFooterView = createSpinnerFooter()                   GLIMPSE_ALL_USERS_DATA.order(by: TIMESTAMP, descending: true).start(afterDocument: lastDocument!).limit(to: 3)           .getDocuments { [self] (snapshot, error ) in                           DispatchQueue.main.async {               self.glimpseTableView.tableFooterView = nil             }                           guard let last = snapshot?.documents.last else { return }             for dictionary in snapshot!.documents {             let name = dictionary[FIRST_NAME] as? String ?? ""             let age = dictionary[AGE] as? String ?? ""             let city = dictionary[CURRENT_CITY] as? String ?? ""             let profileImageURL = dictionary[PROFILE_IMAGE_URL] as? String ?? ""             let glimpseCaption = dictionary[GLIMPSE_CAPTION] as? String ?? ""             let glimpseURL = dictionary[GLIMPSE_IMAGE_URL] as? String ?? ""             let timestamp = dictionary[TIMESTAMP] as? Double ?? 0.0             let documentID = dictionary.documentID             let glimpseInfo = Glimpse(name: name, age: age, city: city, profileImageURL: profileImageURL, glimpseCaption: glimpseCaption, glimpseURL: glimpseURL, timestamp: Date(timeIntervalSince1970: timestamp), documentID: documentID)               self.glimpse.append(glimpseInfo)               self.glimpseTableView.reloadData()             }             self.lastDocument = last         }}     } //This is what i use to delete the post func optionsMenu(sendUser: String) {           let alert = UIAlertController(title: "MyApp", message: "Options", preferredStyle: .actionSheet)     alert.view.tintColor = .brick           let deleteGlimpse = UIAlertAction(title: "Delete Post", style: .default) { (action) in       GLIMPSE_USER_COLLECTION.delete() { err in         if let err = err {           print("COULD NOT REMOVE GLIMPSE...\(err.localizedDescription)")         } else {           print("IMG HAS BEEN DELETED")         }}       GLIMPSE_USER_STORAGE.delete()       self.handleRefresh()     }           let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)     alert.addAction(deleteGlimpse)     alert.addAction(cancelAction)           if let popoverController = alert.popoverPresentationController {       popoverController.sourceView = self.view       popoverController.backgroundColor = .green       popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)       popoverController.permittedArrowDirections = []     }     self.present(alert, animated: true, completion: nil)   }
Topic: UI Frameworks SubTopic: UIKit Tags:
Sep ’21
Reply to UITableView display first 5 rows of an array
I was able to find a solution for this. Here is the updated code: func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) - Int {     return array.count   }       func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) - UITableViewCell {     let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell     cell.cellLbl?.text = array[indexPath.row]           cell.blurView.isHidden = true     if indexPath.row = 5 {               cell.blurView.isHidden = false     }     return cell   }
Topic: Programming Languages SubTopic: Swift Tags:
May ’21