別のエンティティと「1 対多」の関係にあるエンティティに格納されている値を更新するのに苦労しています。
私のプロジェクトは予算管理アプリです。NSFetchedResultsController を使用して、トランザクション (テーブルに入力される) を正常に追加し、FRC が自動的に保存するトランザクションを削除できます。
属性「name」と「amount」を持つトランザクションを格納するエンティティがあり、トランザクションの日付を格納する 1 つの属性「theDate」(NSDate) を持つ別のエンティティがあります。
別の理由は、これにより組織的にシンプルになり、多くのトランザクションが同じ日に発生する可能性があると私が信じていたからです。
以下では、エンティティを作成し、新しいトランザクションを作成した後に値を保存してから、関係を設定します。
@IBAction func done(segue: UIStoryboardSegue) {
let addTransactionVC = segue.sourceViewController as! AddTransaction
let newTrans = addTransactionVC.newTransaction
let date = addTransactionVC.datePicker.date
// Create Entities
let entity = NSEntityDescription.entityForName("DailyTransactions", inManagedObjectContext: self.managedContext)
let relatedEntity = NSEntityDescription.entityForName("TransDates", inManagedObjectContext: self.managedContext)
// Initialize Record
let record = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: self.managedContext)
let recordDate = NSManagedObject(entity: relatedEntity!, insertIntoManagedObjectContext: self.managedContext)
// Is new transaction being created or an old one being edited?
if !addTransactionVC.isEditingTransaction {
// Populate Record
record.setValue(newTrans.name, forKey: "transName")
record.setValue(newTrans.amount, forKey: "transAmount")
recordDate.setValue(date, forKey: "theDate")
// Create Relationship of Date to Transaction
record.setValue(recordDate, forKey: "date")
} else {
// If user was editing a transaction:
let updatedObject = addTransactionVC.managedObject
let newDate = addTransactionVC.datePicker.date
// How do I change the date associated with this transaction?
updatedObject.setValue(newTrans.name, forKey: "transName")
updatedObject.setValue(newTrans.amount, forKey: "transAmount")
// This line was meant to access the attribute in the "date" relationship:
updatedObject.setValue(newDate, forKey: "date")
上記のすべてが正常にelse動作します。Afterelseセル (トランザクション) が編集対象として選択された場合にトリガーされます。この行: updatedObject.setValue(newDate, forKey: "date")TransDates エンティティの "theDate" 属性を単純に更新することを意図していました ("date" は関係の名前です)。しかし、なぜそれがうまくいかないのかがわかりました。
だから私はelseステートメントでこれを試しました:
let fetchRequestDates = NSFetchRequest(entityName: "TransDates")
do {
let dateObjects = try self.managedContext.executeFetchRequest(fetchRequestDates) as! [TransDates]
for dateObject in dateObjects {
// These 2 lines were to test that a date was being returned:
let tempDate = dateObject.theDate as! NSDate
print("dateObject is:\n\(String(tempDate))")
if dateObject.valueForKey("theDate") as! NSDate == newDate {
updatedObject.setValue(dateObject, forKey: "date")
break
}
}
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
上記は単純にすべての TransDates オブジェクトの配列を返し、一致が見つかった場合 (配列の内容と新しい NSDate の両方) に updatedObject が追加されると考えました。それ以外の場合は、いくつかのコードを追加して新しい NSManagedObject としての newDate など。
ただし、if dateObject.valueForKey("theDate") as! NSDate == newDate {これを実行すると、「致命的なエラー: オプション値のラップ解除中に予期せず nil が見つかりました」が発生します。
私の2つの質問:
トランザクションに関連付けられている日付の更新/変更を達成しようとしているという点では (日付が既に存在し、他のトランザクションが含まれている場合、このトランザクションは移動してそれらに参加するだけです)、これが最善の方法ですか? ?
私は関係の目的/機能をすべて間違っていますか?
この長々とした質問で申し訳ありませんが、私はここで何日も立ち往生しています。それでは、よろしくお願いします!