2016-02-21 2 views
0

У меня есть ViewController, который сохраняет входные данные пользователя в CoreData и после попытки сохранения отображается MBProgressHUD, чтобы указать, было ли сохранение успешным или нет.MBProgressHUD вызывает приложение iOS для сбоя (Swift 2.0)

У меня есть класс AddNewViewController

class AddNewViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate { 

@IBOutlet weak var inputErrorMessage: UILabel! 
    @IBOutlet weak var nameLabel: UILabel! 
    @IBOutlet weak var amountLabel: UILabel! 
    @IBOutlet weak var dayPicker: UIPickerView! 
    @IBOutlet weak var durationPicker: UIPickerView! 
    @IBOutlet weak var nameTextField: UITextField! 
    @IBOutlet weak var amountTextField: UITextField! 
    @IBOutlet weak var notesTextField: UITextField! 

//variable to contrain the origin view controller 
var originVC: String? 

    // variables to hold user input 
    var name: String? 
    var amount: Double? 
    var notes: String? 
    var durationDay: Double? 
    var durationType: String? 

// The days and duration options to display in the pickers 
    var durationPickerDataSource = ["Day(s)","Week(s)","Month(s)","Year(s)"]; 
    var dayPickerDataSource = ["1","2","3","4","5","6","7","8","9","10","11","12"]; 

@IBAction func saveButton(sender: AnyObject) { 
     CoreDataStatic.data.saveIncomeBudgetAndExpenses(originVC!, name: name!, amount: amount, durationDay: durationDay!, durationType: durationType!, notes: notes!) 
    } 


/** 
    The number of columns in the picker view. 
    */ 
    func numberOfComponentsInPickerView(dayPickerView: UIPickerView) -> Int { 
     return 1 
    } 

    /** 
    The number of items in the picker view. Equal to the number of days(12) and duration options(4) . 
    */ 
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
     if pickerView == durationPicker { 
      return durationPickerDataSource.count; 
     } 
     else { 
      return dayPickerDataSource.count; 
     } 
    } 

    /** 
    Gets the titles to use for each element of the picker view. 
    */ 
    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 
     if pickerView == durationPicker{ 
      durationType = durationPickerDataSource[row] 
      return durationType 
     } 
     else { 
      durationDay = Double(dayPickerDataSource[row]) 
      return dayPickerDataSource[row] 
     } 
    } 
/** 
    Display acknowledgement if the Income, Budget or Fixed Expense saved. 
    */ 
    func displayMessage(origin: String) { 
     var message : String 

     //Changes the message depending on what the user was trying to save. 
     if CoreDataStatic.data.saved == true { 
     message = "\(origin) saved!" 
        } 
     else if CoreDataStatic.data.saved == false { 
      message = "Error: \(origin) failed to save!" 
     } 
     else { 
      message = "Error!" 
     } 

     print(message) 

     //displays acknowledgement for 2 seconds. 
     /*let acknowledgement = MBProgressHUD.showHUDAddedTo(self.view, animated: true) 
     acknowledgement.mode = MBProgressHUDMode.Text 
     acknowledgement.label.text = message 
      acknowledgement.hideAnimated(true, afterDelay: 2)*/ 
    } 

override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view. 

     self.durationPicker.dataSource = self; 
     self.durationPicker.delegate = self; 
     self.dayPicker.dataSource = self; 
     self.dayPicker.delegate = self; 
    } 

CoreData класс:

struct CoreDataStatic { 
    static let data = CoreData() 
} 

public class CoreData { 

    var appDel : AppDelegate 

    //Manage a collection of managed objects. 
    let context : NSManagedObjectContext 

    //Describes an entity in Core Data. 
    let incomeEntity : NSEntityDescription 
    let budgetEntity : NSEntityDescription 
    let fixedExpenseEntity : NSEntityDescription 

    //Retrieve data from Core Data with the entity 'Scores'. 
    let income = NSFetchRequest(entityName: "Income") 
    let budget = NSFetchRequest(entityName: "Budget") 
    let fixedExpense = NSFetchRequest(entityName: "FixedExpenses") 

    //Set the key that needs updating which is always 'score' 
    let nameKeyToUpdate = "name" 
    let amountDayKeyToUpdate = "amountDay" 
    let amountWeekKeyToUpdate = "amountWeek" 
    let amountMonthKeyToUpdate = "amountMonth" 
    let amountYearKeyToUpdate = "amountYear" 
    let durationDayKeyToUpdate = "durationDay" 
    let durationTypeKeyToUpdate = "durationType" 
    let notesKeyToUpdate = "notes" 

    var saved : Bool? 

func saveIncomeBudgetAndExpenses(origin: String, name: String, amountDay: Double, amountWeek: Double, amountMonth: Double, amountYear: Double, durationDay: Double, durationType: String, notes: String) { 

     //saving in enity depending on origin view controller 
     let entity : NSEntityDescription 
     if origin == "Income" { 
      entity = NSEntityDescription.entityForName("Income", inManagedObjectContext: context)! 
     } 
     else if origin == "Budget" { 
      entity = NSEntityDescription.entityForName("Budget", inManagedObjectContext: context)! 
     } 
     else { 
      entity = NSEntityDescription.entityForName("FixedExpenses", inManagedObjectContext: context)! 
     } 

     let saveNew = NSManagedObject(entity: entity, 
      insertIntoManagedObjectContext:context) 

     // add user input to the relevant entity 
     saveNew.setValue(name, forKey: nameKeyToUpdate) 
     saveNew.setValue(amountDay, forKey: amountDayKeyToUpdate) 
     saveNew.setValue(amountWeek, forKey: amountWeekKeyToUpdate) 
     saveNew.setValue(amountMonth, forKey: amountMonthKeyToUpdate) 
     saveNew.setValue(amountYear, forKey: amountYearKeyToUpdate) 
     saveNew.setValue(durationDay, forKey: durationDayKeyToUpdate) 
     saveNew.setValue(durationType, forKey: durationTypeKeyToUpdate) 
     saveNew.setValue(notes, forKey: notesKeyToUpdate) 


    do { 
    try context.save() 
     print("saved") 
     saved = true 
    } 
    catch _ { 
     print("didnt save") 
     saved = false 
     } 

     AddNewViewController().displayMessage(origin) 
    } 

    init(){ 
     appDel  = (UIApplication.sharedApplication().delegate as! AppDelegate) 
     context  = appDel.managedObjectContext 
     incomeEntity = NSEntityDescription.entityForName("Income", inManagedObjectContext: context)! 
     budgetEntity = NSEntityDescription.entityForName("Budget", inManagedObjectContext: context)! 
     fixedExpenseEntity = NSEntityDescription.entityForName("FixedExpenses", inManagedObjectContext: context)! 
    } 
} 

Этот код работает как и ожидалось, однако, когда закомментирована раздел в displayMessage() функция раскомментирована я получаю следующая ошибка: «фатальная ошибка: неожиданно обнаружена нуль при развертывании дополнительного значения»

из-за линии self.duratio nPicker.dataSource = self; в переопределении viewDidLoad()

Любая помощь будет оценена по достоинству.

Замечание * Если я вызываю displayMessage() в функции saveButton, код работает так неуверенно, почему он не работает при вызове сообщения из класса CoreData.

ответ

0

Я не уверен, что это правильный способ, но я нашел исправление.

переменная (bool) была создана под названием попыткаSave, которая по умолчанию имеет значение false.

в пределах saveIncomeBudgetAndExpenses попробуйте и поймать, попыткаSave изменилась на true.

Функция displayMessage() теперь вызывается в обоих нажатиях кнопок с помощью оператора if, чтобы проверить, является ли попыткаSave да, если да, функция вызова.

Смежные вопросы