swiftuiviewcontrollersegueinstantiationuistoryboardsegue

fatal errors with optionals not making sense


I keep getting a fatal error saying how a value was unwrapped and it was nil and I don't understand how. When I instantiate a view controller with specific variables they all show up, but when I perform a segue to the exact VC, the values don't show up.

Take these functions for example...

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    
  
    
    if let displayVC = storyboard?.instantiateViewController(withIdentifier: Constants.Storyboards.TeachStoryboardID) as? SchoolEventDetailsViewController {
        
        displayVC.selectedEventName = events[indexPath.row].eventName
        displayVC.selectedEventDate = documentsDate[indexPath.row].eventDate
        displayVC.selectedEventCost = documentsCost[indexPath.row].eventCost
        displayVC.selectedEventGrade = documentsGrade[indexPath.row].eventGrade
        displayVC.selectedEventDocID = documentsID[indexPath.row]?.docID
        
        navigationController?.pushViewController(displayVC, animated: true)
    }
}

This combined with this function :

func verifyInstantiation() {
    if let dateToLoad = selectedEventDate {
        dateEditableTextF.text = dateToLoad
    }
    
    if let costToLoad = selectedEventCost {
        costEditableTextF.text = costToLoad
    }
    
    if let gradesToLoad = selectedEventGrade {
        gradesEditableTextF.text = gradesToLoad
    }
    
    if let docIDtoLoad = selectedEventDocID {
        docIDUneditableTextF.text = docIDtoLoad
    }
    
    if let eventNameToLoad = selectedEventName {
        eventNameEditableTextF.text = eventNameToLoad
    }
}

Helps load the data perfectly, but when I try to perform a segue from a search controller the data is not there.

override func viewDidLoad() {
    super.viewDidLoad()
    
    navigationItem.title = selectedEventName

I set the title of the vc to have the event name , and I also recently added a text field to store it as well for experimental purposes (this question).

Now the issue is I want to do a data transfer from an Algolia Search Controller to that VC and I got all the other fields to show up, except for one and that was the document ID. So I created a completion handler function to get the document ID as a string and have it inserted into the vc when the segue is performed, just like how it's there when the vc is instantiated.

Here is the function :

func getTheEventDocID(completion: @escaping ((String?) -> ())) {
    documentListener = db.collection(Constants.Firebase.schoolCollectionName).whereField("event_name", isEqualTo: selectedEventName ?? navigationItem.title).addSnapshotListener(includeMetadataChanges: true) { (querySnapshot, error) in
        if let error = error {
            print("There was an error fetching the documents: \(error)")
        } else {
            self.documentsID = querySnapshot!.documents.map { document in
                return EventDocID(docID: (document.documentID) as! String)
            }
            let fixedID = "\(self.documentsID)"
            let substrings = fixedID.dropFirst(22).dropLast(3)
            let realString = String(substrings)
            completion(realString)
        }
    }
}

I thought either selectedEventName or navigationItem.title would get the job done and provide the value when I used the function in the data transfer function which I will show now :

 //MARK: - Data Transfer From Algolia Search to School Event Details
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    
    otherVC.getTheEventDocID { (eventdocid) in
        if let id = eventdocid {
            if segue.identifier == Constants.Segues.fromSearchToSchoolEventDetails {
                let vc = segue.destination as! SchoolEventDetailsViewController
                vc.selectedEventName = self.nameTheEvent
                vc.selectedEventDate = self.dateTheEvent
                vc.selectedEventCost = self.costTheEvent
                vc.selectedEventGrade = self.gradeTheEvent
                vc.selectedEventDocID = id
            }
        }
    }
 
    
}

But it ends up showing nothing when a search result is clicked which is pretty upsetting, I can't understand why they're both empty values when I declared them in the SchoolEventDetailsVC. I tried to force unwrap selectedEventName and it crashes saying there's a nil value and I can't figure out why. There's actually a lot more to the question but I just tried to keep it short so people will actually attempt to read it and help since nobody ever reads the questions I post, so yeah thanks in advance.


Solution

  • Ok so I decided to attempt a workaround and completely ditched the getTheEventDocID() method because it was just causing me stress. So I decided to ditch Firebase generated document IDS and just use 10 digit generated ids from a function I made. I also figured out how to add that exact same 10 digit id in the Algolia record by just storing the random 10 digit id in a variable and using it in both places. So now instead of using a query call to grab a Firebase generated document ID and have my app crash everytime I click a search result, I basically edited the Struct of the Algolia record and just added an eventDocID property that can be used with hits.hitSource(at: indexPath.row).eventDocID.

    And now the same way I added the other fields to the vc by segue data transfer, I can now do the same thing with my document ID because everything is matching :).