我的应用程序将显示老师的表象,在第一个控制器中,老师需要选择正确的对(第一,第二,第三对),然后在我的代码中写入必要的数据(如科目名称,房间,组数)如果我在第一对中写入数据并保存,它将显示给我,但是,如果我在第二对中写入数据并选择保存按钮,则第一对中的先前数据将丢失,因此我在丢失数据时遇到问题,这是代码对于我选择配对的控制器:
class ChoosePair: UIViewController {
enum choosePair: Int{
case FirstPair = 21
case SecondPair = 22
case ThirdPair = 23
case FourPair = 24
}
@IBAction func PairButtons(_ sender: UIButton){
guard let day = choosePair.init(rawValue: sender.tag) else { return }
switch day {
case .FirstPair:
let FirstPair = self
UserDefaults.standard.set(21, forKey: "pairId")
performSegue(withIdentifier: "SheduleTeacher", sender: self)
break
case .SecondPair:
let SecondPair = self
UserDefaults.standard.set(22, forKey: "pairId")
performSegue(withIdentifier: "SheduleTeacher", sender: SecondPair)
break
case .ThirdPair:
let ThirdPair = self
UserDefaults.standard.set(23, forKey: "pairId")
performSegue(withIdentifier: "SheduleTeacher", sender: ThirdPair)
break
case .FourPair:
let FourPair = self
UserDefaults.standard.set(24, forKey: "pairId")
performSegue(withIdentifier: "SheduleTeacher", sender: FourPair)
break
}
}
}
还有第二个控制器的代码(我在其中写入数据并将其保存在CoreData中)
class SheduleTeacher: UIViewController {
var pairId = UserDefaults.standard.integer(forKey: "pairId")
@IBOutlet weak var subjectLabel: UILabel!
@IBOutlet weak var roomLabel: UILabel!
@IBOutlet weak var timeLabel: UILabel!
@IBOutlet weak var emailLabel: UILabel!
@IBOutlet weak var groupLabel: UILabel!
@IBOutlet weak var captainLabel: UILabel!
@IBOutlet weak var subjectField: UITextField!
@IBOutlet weak var roomField: UITextField!
@IBOutlet weak var timeField: UITextField!
@IBOutlet weak var emailField: UITextField!
@IBOutlet weak var groupField: UITextField!
@IBOutlet weak var captainField: UITextField!
let appDelegate = UIApplication.shared.delegate as! AppDelegate
override func viewDidLoad() {
super.viewDidLoad()
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
subjectField.text = data.value(forKey: "subject\(pairId)") as? String
roomField.text = data.value(forKey: "room\(pairId)") as? String
timeField.text = data.value(forKey: "time\(pairId)") as? String
emailField.text = data.value(forKey: "emailGroup\(pairId)") as? String
groupField.text = data.value(forKey: "group\(pairId)") as? String
captainField.text = data.value(forKey: "captain\(pairId)") as? String
}
} catch {
print("Failed")
}
subjectLabel.layer.borderWidth = 1.0
roomLabel.layer.borderWidth = 1.0
timeLabel.layer.borderWidth = 1.0
emailLabel.layer.borderWidth = 1.0
groupLabel.layer.borderWidth = 1.0
captainLabel.layer.borderWidth = 1.0
}
@IBAction func saveButton(_ sender: UIButton) {
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Users", in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
newUser.setValue(self.subjectField!.text, forKey: "subject\(pairId)")
newUser.setValue(self.roomField!.text, forKey: "room\(pairId)")
newUser.setValue(self.timeField!.text, forKey: "time\(pairId)")
newUser.setValue(self.emailField!.text, forKey: "emailGroup\(pairId)")
newUser.setValue(self.groupField!.text, forKey: "group\(pairId)")
newUser.setValue(self.captainField!.text, forKey: "captain\(pairId)")
do {
try context.save()
} catch {
print("Failed saving")
}
}
}
并拍照我现在在CoreData中拥有的
答案 0 :(得分:0)
谓词用于将获取限制为仅获取某些实体。
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
request.returnsObjectsAsFaults = false
不设置谓词,因此它总是返回那里的所有Users
实体。下面让您遍历每个实体,这就是为什么存在for循环的原因。
for data in result as! [NSManagedObject] {
这是一个示例,您可以使用谓词仅获取带有entity.pairId == pairId
的实体。
override func viewDidLoad() {
super.viewDidLoad()
let context = AppDelegate.shared.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
request.returnsObjectsAsFaults = false
request.predicate = NSPredicate(format: "pairId = %@", argumentArray: [pairId])
do {
let results = try context.fetch(request)
guard results.count == 1 else {
fatalError("Bad count: \(results.count)")
}
guard let data = results.first! as? NSManagedObject else {
fatalError("No NSManagedObject")
}
context.performAndWait {
subjectField.text = data.value(forKey: "subject\(pairId)") as? String
roomField.text = data.value(forKey: "room\(pairId)") as? String
timeField.text = data.value(forKey: "time\(pairId)") as? String
emailField.text = data.value(forKey: "emailGroup\(pairId)") as? String
groupField.text = data.value(forKey: "group\(pairId)") as? String
captainField.text = data.value(forKey: "captain\(pairId)") as? String
}
} catch {
print("Failed")
}
// ...
}
为使谓词正常工作,实体当然必须具有所述属性pairId
。
您也可以在save()
方法中执行类似的操作。如果不存在,您可以在此处更新检索到的Users
实体/创建一个新实体。
一种选择是删除旧的(如果存在的话),并始终在保存时创建一个新的。
“如果一个按钮不存在则创建一个新按钮”的另一种选择是为所有四个按钮预先创建,然后在保存时获取实体并在那里进行更新。但是,您还必须检查启动是否已经存在,否则将在每个启动四个上创建。
答案 1 :(得分:0)
在saveButton
函数中,每次创建一个新的Users实例,这意味着第二对的数据不会与第一对的数据一起写入,而是单独记录。您需要更新现有的对象,而不是在viewDidLoad
中获取的对象。 (我非常怀疑是否会丢失任何数据)
话虽这么说,但我认为您需要重新考虑您的设计,在同一实体中具有重复的(或更多)字段看起来像一个笨拙的设计,将很难维护。更好的解决方案是只具有一个组属性,一个主题属性等等,并用包含pairId的属性对其进行补充。
还有,为什么实体名称为Users,似乎没有任何类型的用户ID?