2016-02-21 80 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()

任何幫助,將不勝感激。

注意*如果我調用saveButton函數中的displayMessage(),代碼的工作原理就很難確定爲什麼從CoreData類調用消息時它不工作。

回答

0

我不確定這是否是正確的方式,但我找到了一個修復程序。

一個變量(布爾)被創建,名爲attemptSave,默認爲false。

在saveIncomeBudgetAndExpenses內嘗試並捕獲,將attemptSave更改爲true。

現在,在兩個按鈕單擊中使用if語句調用displayMessage()函數來檢查attemptSave是否爲yes,如果是,則調用函數。