我的目标是在编辑文本后按完成按钮来更新核心数据中的对象。
完成按钮和下面的文本字段:
这是我的一些代码,
@objc func doneTapped() {
do {
try context.save()
} catch {
print("Error saving the new information \(error)")
}
dateEditableTextF.resignFirstResponder()
selectedEventDate = dateEditableTextF.text
dateEditableTextF.isEnabled = false
costEditableTextF.resignFirstResponder()
selectedEventCost = costEditableTextF.text
costEditableTextF.isEnabled = false
gradesEditableTextF.resignFirstResponder()
selectedEventGrade = gradesEditableTextF.text
gradesEditableTextF.isEnabled = false
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped))
}
我预计,当我在编辑文本字段后运行应用程序时按下完成按钮时,信息会更新,并且当我返回视图控制器时,信息将是相同的,并且我的核心数据数据库将使用更新更新该对象的属性。
实际发生的情况是,当我完成编辑文本字段时,视图控制器中的数据会更新,但是当我离开视图控制器并返回时,数据会恢复为旧条目。
我观看了大约 4 个有关 crud 方法的 YouTube 视频,它们都是不同的场景,与我的不匹配,所以我希望这里有人可以提供帮助。预先感谢。
这是我的视图控制器的其余部分。
@IBOutlet weak var costEditableTextF: UITextField!
@IBOutlet weak var dateEditableTextF: UITextField!
@IBOutlet weak var gradesEditableTextF: UITextField!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var updateTheEvents = [Event]()
var selectedEventName: String?
var selectedEventDate: String?
var selectedEventCost: String?
var selectedEventGrade: String?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = selectedEventName
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped))
if let dateToLoad = selectedEventDate {
dateEditableTextF.text = selectedEventDate
}
if let costToLoad = selectedEventCost {
costEditableTextF.text = selectedEventCost
}
if let gradesToLoad = selectedEventGrade {
gradesEditableTextF.text = selectedEventGrade
}
// Do any additional setup after loading the view.
}
@objc func editTapped() {
dateEditableTextF.becomeFirstResponder()
dateEditableTextF.isEnabled = true
costEditableTextF.isEnabled = true
gradesEditableTextF.isEnabled = true
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneTapped))
}
首先,您需要创建一个存储来管理您的 persistenceContainer 和 CRUD 操作:
class PersistenceManager {
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "your_xcdatamodeld_name") //Here you should type the name of your xcdatamodeld file without the extension .xcdatamodeld
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
return container
}()
}
现在要保存数据,您需要一个上下文。我强烈建议您使用全局的。我在从外部函数访问商店上下文时遇到了几个问题(即未添加/编辑内容)。 请注意,尽管它对我来说非常有效,但我不确定全球环境是否是最佳实践。不过,我还遇到过任何问题。
在
PersistenceManager
类中,在 persisterContainer 之前放置以下代码
static let shared = PersistenceManager()
var managedObjectContext: NSManagedObjectContext {
persistentContainer.viewContext
}
并且,在课前和课外放置以下内容
let context = PersistenceManager.shared.managedObjectContext
...
class PersistenceManager { [...] }
现在你必须像这样创建你的保存函数:
func saveContext () {
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
这属于
PersistenceManager
类的内部。
现在是有趣的部分:您必须创建 CRUD 函数。这些都将位于您的 PersistenceManager 类中。我将向您展示一个有关创建和编辑实体的小演示。
假设您有一个名为“Item”的实体,它具有属性名称和价格。
要保存每个项目,您将拥有如下所示的功能:
func creaateNewItem(name: String, price: Int) -> Item {
let entity = NSEntityDescription.entity(forEntityName: Item, in: context)
let newItem = Item(entity: entity!, insertInto: context)
newItem.name = name
newItem.price = price
self.saveContext()
return newItem
}
要编辑该项目,您必须获取它,然后为其分配新值:
func editItem(currentItem: Item, newName: String, newPrice: Int) {
let currentName: String = currentItem.name! //Current name
//Looking for the item to edit
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Item")
request.predicate = NSPredicate(format: "name = %@", currentName)
request.returnsObjectsAsFaults = false
do { //Editing the item
let editedItem = (try context.fetch(request))[0] as! Item
editedItem.name = newName
editedItem.price = newPrice
self.saveContext()
} catch let error {
print("Error \n \((error))")
}
}
正如您在这里看到的,我传递了一些参数,这些参数将允许您自定义您的项目。显然,如果您需要分配默认值,您可以删除这些参数。
现在,在视图控制器中,您将创建一个
Item
数组对象:
my item : [Item]?
其中将装满您的物品。
要通过按栏按钮编辑已保存的项目,您现在只需执行以下操作:
@objc func editMyItem(){
let newName = "Edited Item"
let newPrice = 15
PersistenceManager().editItem(currentItem: item[indexOfYourChoice], newName: newName, newPrice: newPrice)
}
您的项目将被编辑!
请注意,例如,如果您希望文本来自文本字段,则
newPrice
常量将等于该文本字段的文本。
to upadte coredata using a button
@IBAction 函数已更新(_ 发件人:任意){
让 request = NSFetchRequest(entityName: "Collegedata")
let searchstring = self.cName.text // 使用当前cname查找记录
request.predicate = NSPredicate(format: "cname == %@", searchstring!)
do {
let result = try context.fetch(request)
if let oneline = result.first as? NSManagedObject {
oneline.setValue(self.cName.text, forKey: "cname")
oneline.setValue(self.cYr.text, forKey: "cyear")
oneline.setValue(self.cADM.text, forKey: "cadmissionno")
oneline.setValue(self.cDep.text, forKey: "cdepartment")
try context.save()
print("Updated successfully!")
} else {
print("No matching record found to update.")
}
} catch {
print("Error updating data: \(error)")
}
}
}