我想更新数据库中的记录,但我无法弄清楚如何。 具体而言,我正在尝试获取记录,然后在用户点击UISwitch时使用新值更新/保存该记录。
我尝试这个的方法是在我的ViewController.Swift中,并被称为
didChangeSwitchState(#sender: SettingCell, isOn: Bool)
我使用的是锅炉板CoreData模板,它将managedObjectContext放在AppDelegate中。
这是我的模特:
以及生成的代码和创建新条目的方法:
LogItem.swift
class LogItem: NSManagedObject {
@NSManaged var settingLabel: String
@NSManaged var switchState: Bool
class func createInManagedObjectContext(moc: NSManagedObjectContext, label: String, state: Bool) -> LogItem {
let newItem = NSEntityDescription.insertNewObjectForEntityForName("LogItem", inManagedObjectContext: moc) as! LogItem
newItem.settingLabel = label
newItem.switchState = state
return newItem
}
}
ViewController.swift
class ViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate, SettingCellDelegate {
// Retreive the managedObjectContext from AppDelegate
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
// Create the table view as soon as this class loads
//var logTableView = UITableView(frame: CGRectZero, style: .Plain)
var logItems = [LogItem]()
override func viewDidLoad() {
super.viewDidLoad()
if let moc = self.managedObjectContext {
let fetchRequest = NSFetchRequest(entityName:"LogItem")
var error: NSError?
let fetchedResults = moc.executeFetchRequest(fetchRequest, error: &error) as! [NSManagedObject]?
if (fetchedResults?.count == 0) {
// Create some dummy data to work with
var items = [
("Best Animal", true),
("Best Language", true),
("Derp", false),
("Applesauce", false)
]
for (settingLabel, switchState) in items {
LogItem.createInManagedObjectContext(moc,
label: settingLabel, state: switchState)
}
} else {
println("data already exists")
}
fetchLog()
}
}
func fetchLog() {
let fetchRequest = NSFetchRequest(entityName: "LogItem")
let sortDescriptor = NSSortDescriptor(key: "settingLabel", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [LogItem] {
logItems = fetchResults // question... this seems like it would store the entire table as one item in the array... huh?
}
}
func save() {
var error : NSError?
if(managedObjectContext!.save(&error) ) {
println(error?.localizedDescription)
}
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let logItem = logItems[indexPath.row]
println(logItem.switchState)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CustomSettingCell") as! SettingCell
let logItem = logItems[indexPath.row]
cell.settingsLabel?.text = logItem.settingLabel
cell.settingsSwitch.on = logItem.switchState
cell.cellDelegate = self
return cell
}
func didChangeSwitchState(#sender: SettingCell, isOn: Bool) {
let indexPath = self.tableView.indexPathForCell(sender)
managedObjectContext!.save(nil)
var context = managedObjectContext
let fetchRequest = NSFetchRequest()
var entityName = NSEntityDescription.entityForName("LogItem", inManagedObjectContext: self.managedObjectContext!)
fetchRequest.entity = entityName
var error: NSError?
if let cellName = sender.settingsLabel.text {
fetchRequest.predicate = NSPredicate(format: "settingLabel = %@", cellName)
}
var fetchedResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: &error) as? [LogItem]
if let setting = fetchedResults {
if error != nil {
println("An error occurred loading the data")
} else {
var saveError : NSError? = nil
if !managedObjectContext!.save(&saveError) {
println("Could not update record")
} else {
tableView.reloadData()
}
}
}
tableView.reloadData()
}
SettingCell.swift
class SettingCell: UITableViewCell {
@IBOutlet weak var settingsLabel: UILabel!
@IBOutlet weak var settingsSwitch: UISwitch!
var cellDelegate: SettingCellDelegate?
@IBAction func handledSwitchChange(sender: UISwitch) {
self.cellDelegate?.didChangeSwitchState(sender: self, isOn:settingsSwitch.on)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
SettingItem.swift
class SettingItem: NSObject {
var settingName : String?
var switchState : Bool?
override init() {
super.init()
}
init (settingName: String?, switchState : Bool?) {
super.init()
self.settingName = settingName
self.switchState = switchState
}
}
SettingCellDelegate.swift
protocol SettingCellDelegate {
func didChangeSwitchState(# sender: SettingCell, isOn: Bool)
}
最后这是我的输出,
答案 0 :(得分:2)
您在保存之前不会更改LogItem的值。请相应地执行此操作,此代码也可能会生成编译器错误,因为我不熟悉快速语言,我只是编写可能对您有帮助的伪代码。
var fetchedResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: &error) as? [LogItem]
if let setting = fetchedResults {
if error != nil {
println("An error occurred loading the data")
}
else {
//now you have array of LogItem in your case it's one (assuming that you have unique name
//change the item's switch state and then save it
//Please make a count check here before getting the object
/*
if count == 0 -->> record doesn't exist
else -->> record exist
*/
var settingLogItem = setting[0]
settingLogItem.switchState = isOn
var saveError : NSError? = nil
if !managedObjectContext!.save(&saveError) {
println("Could not update record")
}
else {
tableView.reloadData()
}
}
}