Send array from custom cell to another view controller

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 Cell



import 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 Controller


import 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) -> Int {
            return ptdatas.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> 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)
    }

}

Accepted Reply

So, you should have:


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

     let username = // You know what it is
     let timestamp = // ptdata.assigneddate ?
     let numComments = //
     let commentTxt = // ptdata.comments ?
     let userID =  //
     let documentId = //
     let ptname = //     ptdata.ptname ?
     let assignedmd = // ptdata.assignedmd ?
     let comment = Comment(username: username, timestamp: timestamp, numComments: numComments, commentTxt: commentTxt, userId: userId, documentId: documentId, ptname: ptname, assignedmd: assignedmd)
     ptCommentsInCell = comment // THIS WHERE YOU NEED TO SET THE VALUE WITH ITS CONTENT
  }

Replies

Could you show CommentsVC definition ?


Could you log:

func patCommentBtnTapped (ptcomments: [Comment]) {

  self.ptComments = ptcomments
     print("ptcomments", ptcomments)
  performSegue(withIdentifier: "goToComments", sender: self)
}


In addition, I would find it easier to read if ptcomments had not the same name in cell and in VC.


For instance:

class PatdataVC: UIViewController, UITableViewDelegate, UITableViewDataSource, PatCellCommentsDelegate {
   
    @IBOutlet weak var patDataTableView: UITableView!
   
    var ptdatas = [PTData]()
    var ptCommentsToPass = [Comment]()



In addition, I do not see where you set

var ptcomments = [Comment]()

in

PatdataCell


It should be set in configurePatDataCell, probably with

  ptcomments = ptdata.comments

Note: things would be easier to read with another name:

class PatdataCell: UITableViewCell {
    var ptCommentsInCell = [Comment]()

Hi, per your suggestions i updated the code. Hopefully is easier to read (thx for the tip).

The result of this:

func patCommentBtnTapped (ptcomments: [Comment]) { 
  self.ptComments = ptcomments 
     print("ptcomments", ptcomments) 
  performSegue(withIdentifier: "goToComments", sender: self) 
}

it's an empty array:


ptcomments []


I'm a bit confused when you say the following:


In addition, I do not see where you set


var ptcomments = [Comment]()

inPatdataCell

It should be set in configurePatDataCell, probably with


  ptcomments = ptdata.comments


adding the var here (if i understood your comment) :

func configurePatDataCell(ptdata: PTData, delegate: PatCellCommentsDelegate) {
        var ptcomments = [Comment]()
        ptcomments = ptdata.comments


the compiler throws an error: Cannot assign value of type 'String?' to type '[Comment]'



Here is the initial code for CommentsVC


class CommentsVC: UIViewController, UITableViewDelegate, UITableViewDataSource, CommentsDelegate {
   
    @IBOutlet weak var commentTableView: UITableView!
    @IBOutlet weak var addCommentTxt: UITextField!
    @IBOutlet weak var keyboardView: UIView!
   
    var commentsPtData: Comment!
    var ptCommentsFromCell = [Comment]()
    var commentRef: DocumentReference!
    var username: String!
    var commentListener : ListenerRegistration!
    let firestore = Firestore.firestore()
   
   
    override func viewDidLoad() {
        super.viewDidLoad()
        commentTableView.dataSource = self
        commentTableView.delegate = self
        commentTableView.rowHeight = 110
       
        //commentRef = firestore.collection(PTLIST_REF).document(commentsPtData.documentId)
        //        if let name = Auth.auth().currentUser?.displayName{
        //            username = name
        //    }
       
        self.view.bindToKeyboard()
    }


Thank you for your help!

I was not clear enough.


I say that I do not see where you set the content of ptCommentsInCell for a cell.


And you should do it here in configurePatDataCell.


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

     ptCommentsInCell = // THIS WHERE YOU NEED TO SET THE VALUE WITH ITS CONTENT
  }



Could you also post the definition of Comment ?

here it is:



class Comment {
   
    private(set) var username: String!
    private(set) var timestamp: Date!
    private(set) var numComments: Int?
    private(set) var commentTxt: String!
    private(set) var userId: String!
    private(set) var documentId: String!
    private(set) var ptname: String!
    private(set) var assignedmd: String!
   
    init(username: String, timestamp: Date, numComments: Int, commentTxt: String, userId: String, documentId: String, ptname: String, assignedmd: String)
       
    {
        self.username = username
        self.timestamp = timestamp
        self.numComments = numComments
        self.commentTxt = commentTxt
        self.userId = userId
        self.documentId = documentId
        self.ptname = ptname
        self.assignedmd = assignedmd
       
    }
    class func parseData(snapshot: QuerySnapshot?) -> [Comment] {
        var comments = [Comment]()
       
        guard let snap = snapshot else { return comments }
        for document in snap.documents {
            let data = document.data()
            let username = data[USERNAME] as? String? ?? "Anonymous"
            let timestamp = data[TIMESTAMP] as? Date ?? Date()
            let numComments = data[NUM_COMMENTS] as? Int ?? 0
            let commentTxt = data[COMMENTS] as? String ?? ""
            let userId = data[USER_ID] as? String ?? ""
            let documentId = document.documentID
            let ptname = data[PTNAME] as? String ?? ""
            let assignedmd = data[ASSIGNEDMD] as? String ?? ""
           
            let newComment = Comment(username: username!, timestamp: timestamp, numComments: numComments, commentTxt: commentTxt, userId: userId, documentId: documentId, ptname: ptname, assignedmd: assignedmd)
            comments.append(newComment)
        }
       
        return comments
    }
}

So, you should have:


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

     let username = // You know what it is
     let timestamp = // ptdata.assigneddate ?
     let numComments = //
     let commentTxt = // ptdata.comments ?
     let userID =  //
     let documentId = //
     let ptname = //     ptdata.ptname ?
     let assignedmd = // ptdata.assignedmd ?
     let comment = Comment(username: username, timestamp: timestamp, numComments: numComments, commentTxt: commentTxt, userId: userId, documentId: documentId, ptname: ptname, assignedmd: assignedmd)
     ptCommentsInCell = comment // THIS WHERE YOU NEED TO SET THE VALUE WITH ITS CONTENT
  }

hi Claude,


It worked! thank you.

On a separate note, if possible, can you give me a tip on how to get the documentID from Firebase? i need to include that to send it to the CommentCell.


Again, thank you very much!!!

You should open a new thread and describe exactly the problem you have.


I see you get documentID in snapShot. What do you get ? What are you expecting ?

hi,


no prob, i'm going to create a new thread today. I need to grab the documentID from the Firebase collection when i'm adding a comment. This is to allow the user to delete or modify the comment they create. With the document ID i'm going to be able to get to the subcollection to accomplish that.


thank you!

Hi Claude, im sorry to bother. The other issue you were helping me with (https://forums.developer.apple.com/message/380938#380938)

i'm still having the same problem. I can't add comemnts to that thread, i'm not authorized. Should i start a new one? thx!