Не вызывается функция в didLoad

swift
xcode

#1

Почему не вызывается функция с алертом в didLoad методе TVC ? Если данные в переменной есть, то все нормально, функция срабатывает. Но как только запускается без данных, программа игнорирует алерт и идет дальше, где крашится.

override func viewDidLoad() {
        super.viewDidLoad()

        // Load Data from archive file into array.
        classes = ClassUnit.loadFromFile()
        alert()
        ...

}

    func alert() {
        let alert = UIAlertController(title: "A program doesn't have a data", message: "Please, go to Classes Tab and enter data", preferredStyle: .alert)
        
        let action = UIAlertAction(title: "OK", style: .default, handler: { (action) in
            self.performSegue(withIdentifier: "StudentsTabBar", sender: self)})
        
        alert.addAction(action)
        present (alert, animated: true, completion: nil)
    }

#2

а почему именно в didload?!


#3

первый запуск, пустое приложение, пользователь должен ввести данные. А какие еще могут быть варианты?


#4

AlertControllers не вызывается во viewDidLoad!
Хотите вызвать? Тогда в помощь viewWillApper.


#5

viewWillAppear, viewDidAppear)


#6

Тот же результат, без данных не реагирует


#7

Напишите весь код который используете. Потому что вы написали часть кода и гадай что и почему. Алерты не работают в ViewDidLoad из-за отсутствия обработки анимации


#8

Переход на этот TVC осуществляется с общего TabBar Controller

import UIKit

class StudentsTableViewController: UITableViewController, UIPickerViewDataSource, UIPickerViewDelegate {

// MARK: - Load Data: Properties for store.
// Create array of classes - an instance of ClassUnit.
var classes = [ClassUnit]()
// Create one class that will be selected in picker view and will be show a list of students in a table.
var classSelected: ClassUnit?



// MARK: - Load Data: First Launch
override func viewDidLoad() {
    super.viewDidLoad()

    // Load Data from archive file into array of classes.
    classes = ClassUnit.loadFromFile()
    
        alert()

    // Set value in pickerView
    pickerIndex = 0
    // Set index to selectedCLass
    classSelected = classes[pickerIndex!]
    
}


func alert() {
    let alert = UIAlertController(title: "A program doesn't have data", message: "Go to Classes Tab and enter data", preferredStyle: .alert)
    
    let action = UIAlertAction(title: "OK", style: .default, handler: { (action) in
        self.performSegue(withIdentifier: "StudentsTabBar", sender: self)})
    
    alert.addAction(action)
    present (alert, animated: true, completion: nil)
}


override func viewWillAppear(_ animated: Bool) {
   
    alert()
    
    // Update model data
    classes = ClassUnit.loadFromFile()
    // Update values in pickerView
    classesPickerView.reloadAllComponents()
    // Update values in tableView

    tableView.reloadData()
}



@IBOutlet weak var classesPickerView: UIPickerView!
var pickerIndex: Int?


func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return classes.count
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return "\(classes[row].classTitle) - \(classes[row].students.count)"
}


func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    
    pickerIndex = row
    classSelected = classes[pickerIndex!]
    
    tableView.reloadData() 
}



// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
    
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return (classSelected?.students.count)!
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "StudentsCell", for: indexPath)
    
    cell.textLabel?.text = classSelected?.students[indexPath.row]
    return cell
}



@IBAction func deleteStudentButton(_ sender: UIBarButtonItem) {
    
   
    let tableViewEditingMode = tableView.isEditing
   
    tableView.setEditing(!tableViewEditingMode, animated: true)
    
    
    if navigationItem.leftBarButtonItem?.title == "Delete" {
        navigationItem.leftBarButtonItem?.title = "Done"
    } else {
        navigationItem.leftBarButtonItem?.title = "Delete"
    }
}


override func tableView(_ tableView: UITableView,
                        editingStyleForRowAt indexPath: IndexPath) ->
    UITableViewCell.EditingStyle {
        return .delete
}


override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    
    if editingStyle == .delete {
       
        classSelected?.students.remove(at: indexPath.row)
       
        classes[pickerIndex!] = classSelected!
        
        ClassUnit.saveToFile(classes: classes)
       
        tableView.deleteRows(at: [indexPath], with: .automatic)
        
        classesPickerView.reloadAllComponents()
    }
}

#9
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true) //<--- укажите и не надо весь код копипастить туда. А достаточно будет убрать alert() из viewDidLoad
}

#10

поясните насчет какой именно код не надо копипастить. Я просто дописал super.viewWillAppear, убрал из didLoad,но оно все равно крашится.


#11

Скиньте весь проект на почту shoki-bmx@yandex.ru


#12

скинул на почту ссылку на зип с проектом


#13

Так у тебя и проблема не с alert так то, а с классом ClassUnit


#14

Как вы можете что-то брать из массива в котором ничего нет и ждать от него какое нибудь значение? В особенности числовое.


#15

пересмотрите логику свою где ошибка. Ошибка не в алерте, а в массиве что я указал выше. ТУда ничего не приходит и по этому происходит краш


#16

так в этом весь и смысл, чтобы отловить пустой массив.