Posts

Post marked as solved
6 Replies
414 Views
I'm working on a chat app and I configured a function to check if a user is online. I'm able to see if another user is active or not, but, the issue I'm having is that if I scroll down (I'm using a UITableView) other users show as active and they are not. I placed the code inside the UITableViewCell class. Any suggestions as to what could be the problem are greatly appreciated. Here is my code: UITableViewCell `func configureHomeFeedCell(member: Member) { profileImage.loadImage(with: member.imageURL) profileName.text = "\(member.name)" + ", " + "\(member.age)" checkUserOnlineStatus(with: member.documentId) { _ in } } 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 self.onlineViewStatus.backgroundColor = isOnline == true ? .green : .red 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) { self.onlineViewStatus.backgroundColor = isOnline == true ? .green : .red completion(isOnline!) }}} }`
Posted
by eduardo73.
Last updated
.
Post not yet marked as solved
0 Replies
636 Views
Hi, I'm having a problem when opening a push notification to a specific tab when the app is closed/killed. The code below works properly when the app is in the background or in another tab. If closed and I open the push notification, the app opens to the main screen. Any ideas on how can I get it to open to the correct tab when is completely closed? any help is greatly appreciated.    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {              let scene = UIApplication.shared.connectedScenes.first             if let sceneDelegate = scene?.delegate as? SceneDelegate {               if let tabController = sceneDelegate.window?.rootViewController as? UITabBarController {                 tabController.selectedIndex = 1               }             } }
Posted
by eduardo73.
Last updated
.
Post not yet marked as solved
0 Replies
464 Views
Hello, I'm working on this chat app and I have a snapshot listener to keep track the number of messages (with a badge) each user receives. I'm using a table view with pagination. The problem I'm having that I can't figure out is when a user gets a message, the table view duplicates the user, increases the badge number every time a message is received. Then, if i open the messages and then i go back to the first VC, there is another duplicate of the user but with no badge number because it was cleared. Any help is greatly appreciated. VC override func viewDidAppear(_ animated: Bool) {     super.viewDidAppear(animated)           fetchMatches()   } func fetchMatches() {     fetchInfo { matches in       self.match = matches       self.matchedMessagesTV.reloadData()     }   }       func fetchInfo(completion: @escaping([Match]) -> Void) {     if lastDocument == nil {       let query = MATCH_INFO_COLLECTION.document(currentUID!)         .collection("info").order(by: MATCH_TIMESTAMP, descending: false)       query.limit(to: 10).addSnapshotListener { (snapshot, error) in                   guard let last = snapshot?.documents.last else { return }         guard let snap = snapshot else { return }         snap.documentChanges.forEach({ diff in                       let dictionary = diff.document.data()           let memberId = dictionary[DOCUMENT_ID] as? String ?? ""           let memberAge = dictionary[AGE] as? Int ?? 0           let memberName = dictionary[FIRST_NAME] as? String ?? ""           let memberImageUrl = dictionary[PROFILE_IMAGE_URL] as? String ?? ""           let memberCurrentCity = dictionary[CURRENT_CITY] as? String ?? ""           let matchTimestamp = dictionary[MATCH_TIMESTAMP] as? Double ?? 0.0           let messageCounter = dictionary[MESSAGE_COUNTER] as? Int ?? 0                       let matches = Match(memberId: memberId, memberAge: memberAge ,memberName: memberName, memberImageUrl: memberImageUrl, memberCurrentCity: memberCurrentCity, matchTimestamp: Date(timeIntervalSince1970: matchTimestamp), messageCounter: messageCounter)                       self.match.append(matches)           self.memberId = matches.memberId           self.lastDocument = last           completion(self.match)         })       }     } else {       matchedMessagesTV.tableFooterView = createSpinnerFooter()       let query = MATCH_INFO_COLLECTION.document(currentUID!)         .collection("info").order(by: MATCH_TIMESTAMP, descending: false)               DispatchQueue.main.async {         self.matchedMessagesTV.tableFooterView = nil       }       query.start(afterDocument: self.lastDocument!)         .limit(to: 10).addSnapshotListener { (snapshot, error) in                       guard let last = snapshot?.documents.last else { return }           guard let snap = snapshot else { return }           snap.documentChanges.forEach({ diff in                           let dictionary = diff.document.data()             let memberId = dictionary[DOCUMENT_ID] as? String ?? ""             let memberAge = dictionary[AGE] as? Int ?? 0             let memberName = dictionary[FIRST_NAME] as? String ?? ""             let memberImageUrl = dictionary[PROFILE_IMAGE_URL] as? String ?? ""             let memberCurrentCity = dictionary[CURRENT_CITY] as? String ?? ""             let matchTimestamp = dictionary[MATCH_TIMESTAMP] as? Double ?? 0.0             let messageCounter = dictionary[MESSAGE_COUNTER] as? Int ?? 0                           let matches = Match(memberId: memberId, memberAge: memberAge ,memberName: memberName, memberImageUrl: memberImageUrl, memberCurrentCity: memberCurrentCity, matchTimestamp: Date(timeIntervalSince1970: matchTimestamp), messageCounter: messageCounter)                           self.match.append(matches)             self.memberId = matches.memberId             self.lastDocument = last             completion(self.match)                         })         }}   } class Match {       var memberId: String   let memberAge: Int   let memberName: String   let memberImageUrl: String   let memberCurrentCity: String   let matchTimestamp: Date!   let messageCounter: Int       init(memberId: String, memberAge: Int, memberName: String, memberImageUrl: String, memberCurrentCity: String, matchTimestamp: Date, messageCounter: Int) {           self.memberId = memberId     self.memberAge = memberAge     self.memberName = memberName     self.memberImageUrl = memberImageUrl     self.memberCurrentCity = memberCurrentCity     self.matchTimestamp = matchTimestamp     self.messageCounter = messageCounter   } }
Posted
by eduardo73.
Last updated
.
Post not yet marked as solved
0 Replies
903 Views
I'm trying to replicate the image zoom in/out feature we find in IG, the only issue I'm having is when I zoom-in, the image is not covering the entire screen, it only zooms-in inside the cell. This is a regular setup, a table view, a cell, an image view and a label. I'm not sure what I'm missing here. Any help is greatly appreciated: View Controller import UIKit class ViewController: UIViewController, UITableViewDelegate { @IBOutlet weak var tableView: UITableView! var picArray = ["1", "2", "3", "4", "5", "6", "7", "8", "9"] override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self tableView.rowHeight = 300 } } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return picArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! cell let data = picArray[indexPath.item] cell.backgroundColor = .red cell.setupCell(image: data) cell.clipsToBounds = false cell.selectionStyle = .none return cell } } Cell Class import UIKit class cell: UITableViewCell, UIScrollViewDelegate { @IBOutlet var picture: UIImageView! @IBOutlet var caption: UILabel! var zoomEnabled = false var imgCenter:CGPoint? override func awakeFromNib() { super.awakeFromNib() picture.contentMode = .scaleAspectFill picture.isUserInteractionEnabled = true picture.clipsToBounds = false caption.layer.zPosition = -1 let pinch = UIPinchGestureRecognizer(target: self, action: #selector(self.pinch(sender:))) pinch.delegate = self self.picture.addGestureRecognizer(pinch) let pan = UIPanGestureRecognizer(target: self, action: #selector(self.pan(sender:))) pan.delegate = self self.picture.addGestureRecognizer(pan) } override func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } @objc func pan(sender: UIPanGestureRecognizer) { if self.zoomEnabled && sender.state == .began { self.imgCenter = sender.view?.center } else if self.zoomEnabled && sender.state == .changed { let translation = sender.translation(in: self) if let view = sender.view { view.center = CGPoint(x:view.center.x + translation.x, y:view.center.y + translation.y) } sender.setTranslation(CGPoint.zero, in: self.picture.superview) } } @objc func pinch(sender: UIPinchGestureRecognizer) { if sender.state == .began { let currentScale = self.picture.frame.size.width / self.picture.bounds.size.width let newScale = currentScale * sender.scale if newScale > 1 { self.zoomEnabled = true } } else if sender.state == .changed { guard let view = sender.view else {return} let pinchCenter = CGPoint(x: sender.location(in: view).x - view.bounds.midX, y: sender.location(in: view).y - view.bounds.midY) let transform = view.transform.translatedBy(x: pinchCenter.x, y: pinchCenter.y) .scaledBy(x: sender.scale, y: sender.scale) .translatedBy(x: -pinchCenter.x, y: -pinchCenter.y) let currentScale = self.picture.frame.size.width / self.picture.bounds.size.width var newScale = currentScale * sender.scale if newScale < 1 { newScale = 1 let transform = CGAffineTransform(scaleX: newScale, y: newScale) self.picture.transform = transform sender.scale = 1 }else { view.transform = transform sender.scale = 1 } } else if sender.state == .ended { guard let center = self.imgCenter else {return} UIView.animate(withDuration: 0.3, animations: { self.picture.transform = CGAffineTransform.identity self.picture.center = center }, completion: { _ in self.zoomEnabled = false }) } } func setupCell(image: String) { if let image : UIImage = UIImage(named: image) { picture.image = image } } }
Posted
by eduardo73.
Last updated
.
Post marked as solved
12 Replies
1.3k Views
Hello, I'm working on this messaging app where users have the option of blocking other users. The problem I'm having is reloading the UITableView after a user has been blocked. The first block of code is to block the users: MemberVC func blockUserOption(forMember memberData: String, userHasBeenBlocked: Bool, completion: ((Error?) -> Void)?) {     BLOCKED_USERS_COLLECTION.document(currentUID!).getDocument { (snapshot, error) in       let data = [self.memberDocumentID: userHasBeenBlocked]       if snapshot?.exists == true {         BLOCKED_USERS_COLLECTION.document(self.currentUID!).updateData(data)       } else {         BLOCKED_USERS_COLLECTION.document(self.currentUID!).setData(data)       }}} //Here is how I'm executing the code above:        let blockUser = UIAlertAction(title: "Block", style: .default) { (action) in         let alert = UIAlertController(title: "Block", message: "Are you sure you want to block" + " " + "\(self.memberName as Any)?", preferredStyle: .alert)         alert.view.tintColor = .brick                   alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action: UIAlertAction) in           self.blockUserOption(forMember: self.memberDocumentID, userHasBeenBlocked: true, completion: nil)            self.userDefaults.setValue("yes", forKey: RELOAD)         }))         alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action: UIAlertAction!) in         }))         self.present(alert, animated: true, completion: nil)       } Once the user has been blocked, the current view controller gets dismissed and the user goes back to the view controller where the table view needs to reload and remove the blocked user from the list. MemberListVC    override func viewDidAppear(_ animated: Bool) {     super.viewDidAppear(true)     let reloadQuery = userDefaults.string(forKey: RELOAD)           if reloadQuery == "yes" {               self.match.removeAll()               let query = MATCH_INFO_COLLECTION.document(currentUID!)         .collection("info").order(by: 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, matchTimestamp: 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               }       }       userDefaults.setValue("no", forKey: RELOAD)     } else {       print("NOTHING TO DO HERE")     }   }    func filterUsersThatWereBlocked(completion: @escaping([String: Bool]) -> Void) {     guard let currentUid = Auth.auth().currentUser?.uid else { return }     BLOCKED_USERS_COLLECTION.document(currentUid).getDocument { (snapshot, error) in       guard let data = snapshot?.data() as? [String: Bool] else {         completion([String: Bool]())         return       }       completion(data)     }} Now, if I close and re-open the app, the users that were blocked, do not show up. I'm not sure if the issue is because I'm trying to reload the view inside "viewDidAppear", I tried with "viewWillAppear" and the outcome is the same. Any help is greatly appreciated. Thank you!
Posted
by eduardo73.
Last updated
.
Post marked as solved
3 Replies
709 Views
Hello, I'm working on an app that is fetching data from Firebase and the data is loaded in a UITableView. I'm using pagination (loading 3 posts at a time). Users are allowed to delete their own post. The issue I'm having is when the user deletes the post (first from Firebase and then from the array), the tableView removes the user's post, but it also removes (from the view only) the next 2 posts. Then all I see are the next 3 posts and if I scroll up to see the previous ones, the app crashes because the indexPath.row is out of range. Below is my code. Any help is greatly appreciated: override func viewDidLoad() {     super.viewDidLoad()          configureUI()     fetchGlimpseData()     configureRefreshControl()   }    func configureRefreshControl() {     let refreshControl = UIRefreshControl()     refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)     glimpseTableView?.refreshControl = refreshControl   }       private func createSpinnerFooter() -> UIView {     let footerView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 100))     let spinner = UIActivityIndicatorView()     spinner.center = footerView.center     spinner.color = .brick     footerView.addSubview(spinner)     spinner.startAnimating()           return footerView   }  @objc func handleRefresh() {     glimpse.removeAll(keepingCapacity: false)     self.currentKey = nil     fetchGlimpseData()   } func fetchGlimpseData() {       if lastDocument == nil {         GLIMPSE_ALL_USERS_DATA.order(by: TIMESTAMP, descending: true).limit(to: 3)           .getDocuments { [self] (snapshot, error) in.... //this block of code works properly else {         glimpseTableView.tableFooterView = createSpinnerFooter()                   GLIMPSE_ALL_USERS_DATA.order(by: TIMESTAMP, descending: true).start(afterDocument: lastDocument!).limit(to: 3)           .getDocuments { [self] (snapshot, error ) in.......//this block of code works properly    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {     let position = scrollView.contentOffset.y     let maxOffset = scrollView.contentSize.height - scrollView.frame.size.height     if maxOffset - position <= 50 {       fetchGlimpseData()     }} func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {     return glimpse.count   }       func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {     let gCell = glimpseTableView.dequeueReusableCell(withIdentifier: "GlimpseCell", for: indexPath) as! GlimpseCell           gCell.delegateProfilePic = self     gCell.delegateGlimpseZoom = self     gCell.delegateGlimpseOption = self     gCell.configureGlimpseCell(glimpse: glimpse[indexPath.row])     gCell.separatorInset = .init(top: 5, left: 0, bottom: 5, right: 0)     gCell.backgroundColor = .beige     gCell.layer.borderWidth = 1     gCell.layer.borderColor = UIColor.gray.cgColor     gCell.selectionStyle = .none           return gCell   }       func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {     return .delete   }   func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {     return false   }   func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {     guard editingStyle == .delete else { return }     glimpseTableView.beginUpdates()     glimpse.remove(at: indexPath.row)     glimpseTableView.deleteRows(at: [indexPath], with: .automatic)     glimpseTableView.reloadData()     glimpseTableView.endUpdates()   }
Posted
by eduardo73.
Last updated
.
Post not yet marked as solved
2 Replies
915 Views
I have a UITableView with 1 cell and when the array loads I just want for the user to see the content of the first 5 rows and blur the rest. So, if there is an array with 20 items, the first 5 need to be visible and the remaining 15 with a blur. With the code below, I'm able to just add a blur to row 5 only, I can't figure this out. Any help is greatly appreciated. let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light)) 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] if indexPath.row == 5 { visualEffectView.frame = cell.bounds visualEffectView.layer.masksToBounds = true cell.addSubview(visualEffectView) } return cell }
Posted
by eduardo73.
Last updated
.
Post not yet marked as solved
6 Replies
781 Views
Hi, I have a view controller with a searchBar and 2 tableViews. I run a query to Firebase and the results are shown in the top tableView (chargesTableView). The bottom tableView has a listener that when I select a row from the top tableView the values are displayed at the bottom (this is working OK). The searchBar is to filter the results in the top tableView (chargesTableView), the problem I'm having is with the search logic, no matter what I do when I type 1, 2 or 3 letters of the item I'm looking for, I don't get the result I want, sometimes I get an item that contains the first letter or sometimes i don't get anything at all. I don't know what else to do/check/try to get this working as expected. I want to be able to type the first 2,3 letters and get the list of items in the array. Any help is greatly appreciated. Here is my code: class ChargesVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate { var chargesClassFromCell = [Charges]() var filteredCharges = [Charges]() var searchBar = UISearchBar() var inSearchMode: Bool = false override func viewDidLoad() { super.viewDidLoad() searchBar.delegate = self } func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {     searchBar.showsCancelButton = true   }           func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {     searchBar.endEditing(true)     searchBar.showsCancelButton = false     searchBar.text = nil     inSearchMode = false   }    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {     let searchText = searchBar.text!.lowercased()     if searchText.isEmpty || searchText == " " {       inSearchMode = false       chargesTableView.reloadData()     } else {       inSearchMode = true               filteredCharges = chargesClassFromCell.filter({ (searchResult) -> Bool in         return searchResult.chargeDescription.contains(searchText)       })               chargesTableView.reloadData()     }   }  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {     if tableView == chargesTableView {       if inSearchMode {         return filteredCharges.count       } else {         return chargesClassFromCell.count       }     } else { if tableView == patChargesTableView {       }     }     return patChargesClassFromCell.count   }    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {     if tableView == chargesTableView {       let cell = tableView.dequeueReusableCell(withIdentifier: "ChargesCell", for: indexPath) as? ChargesCell               var charges: Charges!       if inSearchMode {         charges = filteredCharges[indexPath.row]       } else {         cell!.configureChargesListCell(charges: chargesClassFromCell[indexPath.row])       }       cell!.charges = charges               return cell!             } else if tableView == patChargesTableView {       let cell = tableView.dequeueReusableCell(withIdentifier: "PatChargesCell", for: indexPath) as? PatChargesCell       cell!.configurePatChargesListCell(patCharges: patChargesClassFromCell[indexPath.row])       cell!.patChargesCount.text = "\(indexPath.row + 1)" + " - "       return cell!     }     return UITableViewCell()   }
Posted
by eduardo73.
Last updated
.
Post marked as solved
6 Replies
540 Views
Hi, I have a cell with 2 buttons. Both buttons need to pass the same array but to 2 different view controllers depending on the user’s selection. The problem I’m having is that I cannot pass the array to one of the VCs, I get this error: “Expression type '()' is ambiguous without more context”. Any help is greatly appreciated. Here is my code:Inside the TableViewCellprotocol PatientDataCellDelegate { func patCommentBtnTapped (ptData: PTData) func dischargeBtnTapped (ptData: PTData) } @IBAction func addCommentBtnTapped(_ sender: UIButton) { //Button to segue to the Comments VC delegate?.patCommentBtnTapped(ptData: ptData) } @IBAction func patientDischargeBtnTapped(_ sender: UIButton) { //Button to segue to the Discharge VC delegate?.dischargeBtnTapped(ptData: ptData) }View Controller override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "goToComments" { if let commtsVC = segue.destination as? CommentsVC { if let ptDatas = sender as? PTData { commtsVC.ptDatas = ptDatas } } } else if segue.identifier == "goToDischarge" { if let discharVC = segue.destination as? DischargeVC { if let ptDataFromCell = sender as? PTData { discharVC.patDischargeFromCell = ptDataFromCell } } } } } extension PatdataVC: PatientDataCellDelegate { func patCommentBtnTapped (ptData: PTData) { //Segue to Comments VC performSegue(withIdentifier: "goToComments", sender: ptData) } func dischargeBtnTapped(ptData: PTData) {. // Segue to Discharge VC performSegue(withIdentifier: "goToDischarge", sender: ptData) } }DischargeVCvar patDischargeFromCell = [DischargePatient]()
Posted
by eduardo73.
Last updated
.
Post not yet marked as solved
14 Replies
942 Views
I’m working on this app that runs 2 different queries to Firebase. The first Firebase query displays the data inside a pickerView, the second is a query to a “users” collection and pulls a custom field. Both queries are working as expected, pickerView displays the info and I’m able to print the results of the user’s collection to the console. The issue I’m having is that I’m trying to pass the value inside the custom field userSpecialtyCode to the next VC and is not working. I'm not sure what I'm missing. Any help is greatly appreciated. Here is my code:class PatfilterVC: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate { @IBOutlet weak var hospNameTxt: UITextField! @IBOutlet weak var getDataBtn: UIButton! @IBOutlet weak var infoPickerViewer: UIPickerView! private var textFieldSelected = UITextField() private var pickerView: UIPickerView? private var handle: AuthStateDidChangeListenerHandle? private var userListener: ListenerRegistration! private var hospitalClass = [HospitalList]() private var hospCollectionRef: CollectionReference! private var hospCode: HospitalList! = nil private var loggedInUserClass = [UserSpecialty]() private var usersCollectionRef: CollectionReference! private var currentUserSpecialty: UserSpecialty! = nil override func viewDidLoad() { super.viewDidLoad() overrideUserInterfaceStyle = .light let pickerView = UIPickerView() infoPickerViewer.delegate = self infoPickerViewer.dataSource = self hospNameTxt.inputView = pickerView hospNameTxt.delegate = self self.infoPickerViewer = pickerView self.infoPickerViewer?.delegate = self self.infoPickerViewer?.dataSource = self self.infoPickerViewer?.reloadAllComponents() hospCollectionRef = Firestore.firestore().collection(HOSPITAL_REF) usersCollectionRef = Firestore.firestore().collection(USERS_REF) handle = Auth.auth().addStateDidChangeListener({ (auth, user) in if user == nil { self.getDataBtn.isUserInteractionEnabled = false self.infoPickerViewer.isUserInteractionEnabled = false } else { self.getDataBtn.isUserInteractionEnabled = true self.infoPickerViewer.isUserInteractionEnabled = true self.setListener() } }) let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIInputViewController.dismissKeyboard)) view.addGestureRecognizer(tap) getHospitalList() getUserSpecialty() } @objc func dismissKeyboard() { view.endEditing(true) } override func viewWillAppear(_ animated: Bool) { handle = Auth.auth().addStateDidChangeListener({ (auth, user) in if user == nil { let storyboard = UIStoryboard(name: "Main", bundle: nil) let LoginVC = storyboard.instantiateViewController(withIdentifier: "LoginVC") self.present(LoginVC, animated: true, completion: nil) } else { self.setListener() } }) } override func viewWillDisappear(_ animated: Bool) { if userListener != nil { userListener.remove() } } func setListener() { } func numberOfComponents(in pickerView: UIPickerView) -&gt; Int { return 1 } func textFieldDidBeginEditing(_ textField: UITextField) { textFieldSelected = textField } func textFieldShouldBeginEditing(_ textField: UITextField) -&gt; Bool { self.pickerView?.reloadAllComponents() return true } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -&gt; Int { return hospitalClass.count } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -&gt; String? { return hospitalClass[row].hospitalName } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { hospCode = hospitalClass[row] let hosp = hospitalClass[row].hospitalName hospNameTxt.text = hosp } @IBAction func getDataTapped(_ sender: Any) { guard hospCode != nil else {return} //I'm able to pass this to ResultsdataVC guard currentUserSpecialty != nil else {return} //I'm not able to pass, value returns nil performSegue(withIdentifier: "goToResults", sender: self) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "goToResults" { let vc = segue.destination as! ResultsdataVC if let hosp = hospCode { vc.hospCodeFromVC = hosp.hospitalCode } if let user = currentUserSpecialty { vc.userSpecFromVC = user.userSpecialtyCode } } } //this query displays in the pickerView func getHospitalList() { let hospListQuery = hospCollectionRef? .order(by: HOSPITAL_NAME, descending: false) hospListQuery?.getDocuments { (snapshot, error) in if let err = error { debugPrint("error fetching docs: \(err)") } else { self.infoPickerViewer.reloadAllComponents() let snap = snapshot for document in snap!.documents { let data = document.data() let hospitalCode = data[HOSPITAL_CODE] as? String ?? "" let hospitalName = data[HOSPITAL_NAME] as? String ?? "" let hospList = HospitalList(hospitalCode: hospitalCode, hospitalName: hospitalName) self.hospitalClass.append(hospList) } } } } //this query gets the values from Firebase but i cannot pass userSpecialtyCode // to the next viewController func getUserSpecialty() { if let loggedInUser = Auth.auth().currentUser?.uid { let docRef = usersCollectionRef.document(loggedInUser) docRef.getDocument { ( document, error) in if let document = document, document.exists { let data = document.data() let userSpecialtyCode = data?[SPECIALTY_CODE] as? String ?? "" let loggedInUserId = data?[LOGGED_IN_USER_ID] as? String ?? "" let loggedUser = UserSpecialty(userSpecialtyCode: userSpecialtyCode, loggedInUserId: loggedInUserId) self.loggedInUserClass.append(loggedUser) print("specCode", userSpecialtyCode as Any) //IT PRINTS THE CORRECT VALUE print("loggedInUser", loggedInUserId as Any) //IT PRINTS THE USER ID } else { print("no document") } } } } @IBAction func logoutTapped(_ sender: Any) { let firebaseAuth = Auth.auth() do { try firebaseAuth.signOut() } catch let signoutError as NSError { debugPrint("Error signing out: \(signoutError)") } } }
Posted
by eduardo73.
Last updated
.
Post marked as solved
2 Replies
788 Views
Hi , I've been working on thsi small project (https://forums.developer.apple.com/message/409478#409478 ) but now i'm stuck with the following. The pickerView is populating the info from Firebase with no issues. Each Firebase collection has 2 strings: itemName and itemCode. The pickerView displays "itemName" only, now, i need to grab the value inside itemCode to send it to the next VC. Here is how i have the pickerView setup:func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -&gt; String? { if labelTxt.isFirstResponder { return itemsClass[row].itemName } return nil } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { if labelTxt.isFirstResponder { let item = itemsClass[row].itemName print("ITEMCODE2", itemsClass[row].itemCode as Any) labelTxt.text = item } } @IBAction func sendInfo(_ sender: Any) { if ITEMS_CODE = { //here I do not know how to load the the second variable inside the ItemInfo. } performSegue(withIdentifier: "goToInfo", sender: self) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "goToInfo" { let vc = segue.destination as! infoVC vc.fromPicker = ITEMS_CODE //This returns nil when i print to the console } }How do I get itemCode so that i can segue to the next VC? Thank you!
Posted
by eduardo73.
Last updated
.
Post marked as solved
6 Replies
1.2k Views
CODE HAS BEEN UPDATED AND IS WORKING AS EXPECTED.Hello, I have a View Controller with a text field and a pickerview. I want to display the data i have stored in Firebase inside the pickerview. I'm able to retrieve and print the data from Firebase but I can't find a way to display it inside the picker view. Here is my code:import UIKit import Firebase class pickerVC: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate { @IBOutlet weak var labelTxt: UITextField! @IBOutlet weak var infoPickerViewer: UIPickerView! var dbRef: CollectionReference! var pickerView: UIPickerView? var itemsClass = [ItemInfo]() override func viewDidLoad() { super.viewDidLoad() let pickerView = UIPickerView() infoPickerViewer.delegate = self infoPickerViewer.dataSource = self dbRef = Firestore.firestore().collection(ITEMS_REF) labelTxt.inputView = pickerView labelTxt.delegate = self self.infoPickerViewer = pickerView self.infoPickerViewer?.delegate = self self.infoPickerViewer?.dataSource = self self.infoPickerViewer.reloadAllComponents() getItems() } func numberOfComponents(in pickerView: UIPickerView) -&gt; Int { return 1 } func textFieldDidBeginEditing(_ textField: UITextField) { labelTxt = textField } func textFieldShouldBeginEditing(_ textField: UITextField) -&gt; Bool { self.pickerView?.reloadAllComponents() return true } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -&gt; Int { if labelTxt.isFirstResponder { return self.itemsClass.count } return 0 } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -&gt; String? { if labelTxt.isFirstResponder { return itemsClass[row].itemName } return nil } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { if labelTxt.isFirstResponder { let item = itemsClass[row].itemName labelTxt.text = item } } func getItems() { dbRef.getDocuments { (snapshot, error) in if let err = error { debugPrint("error fetching docs: \(err)") } else { self.infoPickerViewer.reloadAllComponents() let snap = snapshot for document in snap!.documents { let data = document.data() let itemCode = data[ITEMS_CODE] as? String ?? "" let itemName = data[ITEMS_NAME] as? String ?? "" let t = ItemInfo(itemCode: itemCode, itemName: itemName) self.itemsClass.append(t) print("ITEMS_CODE", itemCode as Any) print("ITEMS_NAME", itemName as Any) } } } } }The Firebase DB is structured as follow:collection/AutoID/itemCode: "item1" itemName: "item2"collection/AutoID/itemCode: "item3" itemName: "item4"I only need to display the itemName inside the pickerview, the itemCode I'm going to use it to run a query.Any help with this is greatly appreciated.
Posted
by eduardo73.
Last updated
.
Post marked as solved
4 Replies
1k Views
ello, i'm running a query to Firebase and i need to get the document ID of the collection. This is the code to run the query:Variableprivate var ptListInCell = [PTList]()@IBAction func getDataTapped(_ sender: Any) { SVProgressHUD.show() if HOSP != (hospnameTxt.text!) { ptListQuery = ptListCollectionRef?.whereField("hosp", isEqualTo: (hospnameTxt.text!)) } ptListQuery?.getDocuments { (snapshot, error) in if let err = error { debugPrint("error getting data: \(err)") } else { guard let snap = snapshot else { return } for document in snap.documents { let data = document.data() let ptName = data[PTNAME] as? String ?? "" let assignedMd = data[ASSIGNEDMD] as? String ?? "" let officeMd = data[OFFICEMD] as? String ?? "" let assignedDate = data[ASSIGNEDDATE] as? String ?? "" let seeNoSee = data[SEENOSEE] as? String ?? "" let room = data[ROOM] as? String ?? "" let app = data[APP] as? String ?? "" let documentId = document.documentID print("documentId", documentId) let newPtList = PTList(ptName: ptName, assignedMd: assignedMd, officeMd: officeMd, assignedDate: assignedDate, seeNoSee: seeNoSee, room: room, app: app, documentId: documentId) print("newPtList", newPtList) print("documentId", documentId) self.ptListInCell.append(newPtList) } }it pulls everything but the documentID. When i print to the console:print(ptlist?.documentId asAny)Result is nil. thank you!
Posted
by eduardo73.
Last updated
.
Post marked as solved
9 Replies
1.8k Views
i'm running a query to Firebase and the results are displaying in a custom cell. The cell has a UIButton that when tapped it goes to another view controller where the user can enter info. The question i have is, how do i send the array in the custom cell to the next view controller? i need to send the array so i can reference the subcollection of info i'm going to add for each array. Segue is working properly, when i print to the console, the array is empty "nil". Any help is greatly appreciated.Custom Cellimport UIKit import Firebase protocol PatCellCommentsDelegate { func patCommentBtnTapped (ptCommentsInCell: [Comment]) } class PatdataCell: UITableViewCell { @IBOutlet weak var ptnameLbl: UILabel! @IBOutlet weak var dobLbl: UILabel! @IBOutlet weak var finLbl: UILabel! @IBOutlet weak var officemdLbl: UILabel! @IBOutlet weak var assignedmdLbl: UILabel? @IBOutlet weak var appnameLbl: UILabel! @IBOutlet weak var assigneddateLbl: UILabel! @IBOutlet weak var roomnumberLbl: UILabel? @IBOutlet weak var diagnosesLbl: UILabel! @IBOutlet weak var reasonforadmitorconsultLbl: UILabel! @IBOutlet weak var goalofhospitalizationLbl: UILabel! @IBOutlet weak var seenoseeLbl: UILabel? @IBOutlet weak var notestocboLbl: UILabel! @IBOutlet weak var numCommentsLbl: UILabel! @IBOutlet weak var hospitalLbl: UILabel! @IBOutlet weak var teamLbl: UILabel! @IBOutlet weak var addCommentBtn: UIButton! var ptdata: PTData! var ptCommentsInCell = [Comment]() var delegate: PatCellCommentsDelegate? override func awakeFromNib() { super.awakeFromNib() } func configurePatDataCell(ptdata: PTData, delegate: PatCellCommentsDelegate) { self.ptdata = ptdata self.delegate = delegate ptnameLbl.text = ptdata.ptname dobLbl.text = ptdata.dob finLbl.text = ptdata.fin officemdLbl.text = ptdata.officemd assignedmdLbl?.text = ptdata.assignedmd appnameLbl.text = ptdata.app assigneddateLbl.text = ptdata.assigneddate roomnumberLbl?.text = ptdata.room diagnosesLbl.text = ptdata.diagnoses reasonforadmitorconsultLbl.text = ptdata.reasonforadmitorconsult goalofhospitalizationLbl.text = ptdata.goalofhospitalization seenoseeLbl?.text = ptdata.seenosee notestocboLbl.text = ptdata.notestocbo numCommentsLbl.text = ptdata.comments hospitalLbl.text = ptdata.hosp teamLbl.text = ptdata.team } @IBAction func addCommentBtnTapped(_ sender: Any) { //trying to send data to commentsVC from this cell delegate?.patCommentBtnTapped(ptCommentsInCell: self.ptCommentsInCell) } }View Controllerimport UIKit import Firebase import SVProgressHUD class PatdataVC: UIViewController, UITableViewDelegate, UITableViewDataSource, PatCellCommentsDelegate { @IBOutlet weak var patDataTableView: UITableView! var ptdatas = [PTData]() var ptCommentsToPass = [Comment]() override func viewDidLoad() { super.viewDidLoad() patDataTableView.delegate = self patDataTableView.dataSource = self patDataTableView.rowHeight = 1150 } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "goToComments" { let commtsVC = segue.destination as! CommentsVC commtsVC.ptComments = ptCommentsToPass SVProgressHUD.dismiss() } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int { return ptdatas.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell { if tableView == patDataTableView { let cell = tableView.dequeueReusableCell(withIdentifier: "PatdataCell", for: indexPath) as? PatdataCell cell!.configurePatDataCell(ptdata: ptdatas[indexPath.row], delegate: self) return cell! } return UITableViewCell() } func patCommentBtnTapped (ptCommentsInCell: [Comment]) { self.ptCommentsToPass = ptCommentsInCell print("ptcomments", ptCommentsInCell) performSegue(withIdentifier: "goToComments", sender: self) } }
Posted
by eduardo73.
Last updated
.
Post not yet marked as solved
10 Replies
1.7k Views
ISSUE HAS BEEN FIXED. SEE POST: https://forums.developer.apple.com/message/374921#374921hello everyone, i'm new at coding and if possible i need help with my app. i'm trying to perform a segue from a button inside a custom cell to another VC. The button inside the cell is querying data from Firebase and grabbing the results from a query and using them to do a bigger query, then it needs to send the data in another VC. Every label within the cell has a value, i dont understand why the SEGUE is not working as excpected. Any help is greatly appreciated. Thank you!**Cell Protocol**protocol MyCellDelegate: class { func sendDataFromCell(_ sender: Any) }**CustomCell: ptlistCell**import UIKit import Firebase import FirebaseFirestore class ptlistCell: UITableViewCell { @IBOutlet private weak var ptnameLbl: UILabel! @IBOutlet private weak var assignedmdLbl: UILabel! @IBOutlet private weak var officemdLbl: UILabel! @IBOutlet private weak var roomnumberLbl: UILabel! @IBOutlet private weak var seenoseeLbl: UILabel! @IBOutlet private weak var assigneddateLbl: UILabel! @IBOutlet weak var ptdataBtn: UIButton! var ptdatainfoRef: CollectionReference! var query: Query? var patdata = [PTData]() var delegate: MyCellDelegate? override func awakeFromNib() { super.awakeFromNib() ptdatainfoRef = Firestore.firestore().collection(PTLIST_REF) } func configureCell(ptlist: PTList) { ptnameLbl.text = ptlist.ptname assignedmdLbl.text = ptlist.assignedmd officemdLbl.text = ptlist.officemd roomnumberLbl.text = ptlist.room seenoseeLbl.text = ptlist.seenosee assigneddateLbl.text = ptlist.assigneddate } @IBAction func ptdataTapped(_ sender: Any) { let query = ptdatainfoRef.whereField("ptname", isEqualTo: (ptnameLbl.text!)) .whereField("assignedmd", isEqualTo: (assignedmdLbl.text!)) .whereField("officemd", isEqualTo: (officemdLbl.text!)) .whereField("room", isEqualTo: (roomnumberLbl.text!)) .whereField("seenosee", isEqualTo: (seenoseeLbl.text!)) .whereField("assigneddate", isEqualTo: (assigneddateLbl.text!)) query.getDocuments { (snapshot, error) in if let err = error { debugPrint("error getting data: \(err)") } else { guard let snap = snapshot else { return } for document in snap.documents { let data = document.data() let ptname = data[PTNAME] as? String ?? "" let dob = data[DOB] as? String ?? "" let fin = data[FIN] as? String ?? "" let officemd = data[OFFICEMD] as? String ?? "" let assignedmd = data[ASSIGNEDMD] as? String ?? "" let assigneddate = data[ASSIGNEDDATE] as? String ?? "" let room = data[ROOM] as? String ?? "" let diagnoses = data[DIAGNOSES] as? String ?? "" let reasonforadmitorconsult = data[REASONFORADMITORCONSULT] as? String ?? "" let goalofhospitalization = data[GOALOFHOSPITALIZATION] as? String ?? "" let seenosee = data[SEENOSEE] as? String ?? "" let notestocbo = data[NOTESTOCBO] as? String ?? "" let comments = data[COMMENTS] as? String ?? "" let hosp = data[HOSP] as? String ?? "" let team = data[TEAM] as? String ?? "" let newPtdata = PTData (ptname: ptname, dob: dob, fin: fin, officemd: officemd, assignedmd: assignedmd, assigneddate: assigneddate, room: room, diagnoses: diagnoses, reasonforadmitorconsult: reasonforadmitorconsult, goalofhospitalization: goalofhospitalization, seenosee: seenosee, notestocbo: notestocbo, comments: comments, hosp: hosp, team: team) self.patdata.append(newPtdata) print(document.data()) };print(self.delegate) if(self.delegate != nil) { self.delegate?.sendDataFromCell(sender) } } } } }**firstVC w customCell (ptlistcell)**import UIKit import Firebase class resultsdataVC: UIViewController, UITableViewDataSource, UITableViewDelegate, MyCellDelegate { @IBOutlet weak var tableView: UITableView! var ptlist: PTList! var ptlists = [PTList]() var tableVc: patdataVC! override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int { return ptlists.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell { if let cell = tableView.dequeueReusableCell(withIdentifier: "ptlistCell", for: indexPath) as? ptlistCell { cell.configureCell(ptlist: ptlists[indexPath.row]) return cell } return UITableViewCell() } func sendDataFromCell(_ sender: Any) { performSegue(withIdentifier: "gotoptdata", sender: (Any).self) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "gotoptdata" { tableVc = segue.destination as? patdataVC tableVc.tableViewCellDelegate = self as? MyCellDelegate } } }**secondVC w customCell (ptdataCell)**import UIKit import Firebase import FirebaseFirestore class patdataVC: UIViewController, UITableViewDelegate, UITableViewDataSource { var ptdata: PTData! var patdata = [PTData]() var tableViewCellDelegate: MyCellDelegate? @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int { return patdata.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell { let cellIdentifier = "ptlistCell" guard let cell = tableView.dequeueReusableCell(withIdentifier: "ptdataCell", for: indexPath) as? ptlistCell else { fatalError("The dequeued cell is not an instance of TableViewCell.") } cell.delegate = tableViewCellDelegate return cell } }**CustomCell: ptdataCell**import UIKit import Firebase class ptdataCell: UITableViewCell { @IBOutlet weak var ptnameLbl2: UILabel! @IBOutlet weak var dobLbl2: UILabel! @IBOutlet weak var finLbl2: UILabel! @IBOutlet weak var officemdLbl2: UILabel! @IBOutlet weak var assignedmdLbl2: UILabel! @IBOutlet weak var assigneddateLbl2: UILabel! @IBOutlet weak var roomLbl2: UILabel! @IBOutlet weak var diagnosesLbl2: UILabel! @IBOutlet weak var reasonforadmitorconsultLbl2: UILabel! @IBOutlet weak var goalofhospitalizationLbl2: UILabel! @IBOutlet weak var seenoseeLbl2: UILabel! @IBOutlet weak var notestocboLbl2: UILabel! @IBOutlet weak var commentsLbl2: UILabel! override func awakeFromNib() { super.awakeFromNib() } func configureCell(patdata: PTData) { ptnameLbl2.text = patdata.ptname dobLbl2.text = patdata.dob finLbl2.text = patdata.fin officemdLbl2.text = patdata.officemd assignedmdLbl2.text = patdata.assignedmd assigneddateLbl2.text = patdata.assigneddate roomLbl2.text = patdata.room diagnosesLbl2.text = patdata.diagnoses reasonforadmitorconsultLbl2.text = patdata.reasonforadmitorconsult goalofhospitalizationLbl2.text = patdata.goalofhospitalization seenoseeLbl2.text = patdata.seenosee notestocboLbl2.text = patdata.notestocbo commentsLbl2.text = patdata.comments } }
Posted
by eduardo73.
Last updated
.