有没有办法通过按栏按钮项来更新核心数据模型中的对象?

问题描述 投票:0回答:2

我的目标是在编辑文本后按完成按钮来更新核心数据中的对象。

完成按钮和下面的文本字段:

enter image description here

这是我的一些代码,

@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))
    
        
    }
swift core-data uinavigationbar crud nsmanagedobject
2个回答
1
投票

首先,您需要创建一个存储来管理您的 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
常量将等于该文本字段的文本。


0
投票

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)")
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.