我想在数据库中更新一条记录,但是我不知道该怎么做。具体来说,我正在尝试获取一条记录,然后在用户点击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)
}
最终这是我的输出结果: