swift3 CoreData的操作十分简单,只需要简单的几个步骤就能完成增删改查
要使用CoreData,需要在新建项目时勾选CoreData选项
新建的项目中会有SwiftDemo2.xcdatamodeld这个文件(SwiftDemo2是项目名)
新增一个entity(相当于数据库的表),添加entity的属性,如下图我新增了一名为"Note"的entity
增
func saveData(content:String){
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
let context:NSManagedObjectContext = appDelegate.persistentContainer.viewContext
let note: Note = Note(context: context)
note.content = content
note.createTime = NSDate()
appDelegate.saveContext()
}
appDelegate.saveContext()是在AppDelegate.swift里自动生成的
查
func getData() -> [Note] {
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
let context:NSManagedObjectContext = appDelegate.persistentContainer.viewContext
var dataList: [Note] = []
let fetchRequest: NSFetchRequest = Note.fetchRequest()
// let predicate = NSPredicate(format: "content='aa'") //增加查询条件
// fetchRequest.predicate = predicate
do {
dataList = try context.fetch(fetchRequest)
} catch {
print(error)
}
return dataList
}
改
func updateData(object:Note,content:String) {
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
object.content = content
appDelegate.saveContext()
}
func deleteData(object:Note) {
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
let context:NSManagedObjectContext = appDelegate.persistentContainer.viewContext
context.delete(object)
appDelegate.saveContext()
}
如果用tableview展示数据,使用上面方法,增加或更新一条数据列表就要重新载入全部数据,性能不好
NSFetchedResultsController可把单元格内容与数据进行绑定,响应数据变化
需要遵从NSFetchedResultsControllerDelegate协议,具体代码如下:
import UIKit
import CoreData
class NoteTableController: UITableViewController,NSFetchedResultsControllerDelegate {
var dataSource:[Note] = [Note]()
var fc:NSFetchedResultsController!
override func viewDidLoad() {
super.viewDidLoad()
// 加载全部数据
let request:NSFetchRequest! = Note.fetchRequest()
let sd = NSSortDescriptor(key: "createTime", ascending: true) // 指定结果如何排序
request.sortDescriptors = [sd]
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
fc = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
fc.delegate = self
do {
try fc.performFetch()
if let results = fc.fetchedObjects {
dataSource = results
}
} catch {
print(error)
}
}
func controllerWillChangeContent(_ controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController) {
tableView.endUpdates()
}
func controller(_ controller: NSFetchedResultsController, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case NSFetchedResultsChangeType.delete:
tableView.deleteRows(at: [indexPath!], with: UITableViewRowAnimation.automatic)
case NSFetchedResultsChangeType.insert:
// 新增一条数据后在列表增加一行,不用重新载入全部数据
tableView.insertRows(at: [newIndexPath!], with: UITableViewRowAnimation.automatic)
case NSFetchedResultsChangeType.update:
tableView.reloadRows(at: [indexPath!], with: UITableViewRowAnimation.automatic)
default:
tableView.reloadData()
}
if let objects = controller.fetchedObjects {
dataSource = objects as! [Note]
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return dataSource.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "rowId")
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "rowId")
}
cell!.textLabel?.text = dataSource[indexPath.row].content
return cell!
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let editView:AddNoteViewController? = self.storyboard?.instantiateViewController(withIdentifier: "editView") as? AddNoteViewController
editView?.editNote = dataSource[indexPath.row]
editView?.editContent = dataSource[indexPath.row].content
self.navigationController?.pushViewController(editView!, animated: true)
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.delete
}
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
context.delete(self.fc.object(at: indexPath))
appDelegate.saveContext()
}
}
override func viewWillAppear(_ animated: Bool) {
tableView.reloadData()
tableView.isEditing = false
editBtn.title = "编辑"
}
@IBOutlet weak var editBtn: UIBarButtonItem!
@IBAction func edit(_ sender: UIBarButtonItem) {
if tableView.isEditing {
tableView.isEditing = false
editBtn.title = "编辑"
} else {
tableView.isEditing = true
editBtn.title = "完成"
}
}
}
import UIKit
import CoreData
class AddNoteViewController: UIViewController,UITextViewDelegate {
@IBOutlet weak var editTextView: UITextView!
var editNote:Note?
var editContent:String?
override func viewDidLoad() {
super.viewDidLoad()
// textview前面不留空行
self.automaticallyAdjustsScrollViewInsets = false
if editContent != nil {
editTextView.text = editContent
}
// 监听键盘打开和收起事件
NotificationCenter.default.addObserver(self, selector: #selector(AddNoteViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(AddNoteViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
@IBAction func complete(_ sender: Any) {
// 收起键盘
editTextView.endEditing(true)
}
@IBAction func saveNote(_ sender: Any) {
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
if editNote != nil { // 更新
editNote?.content = editTextView.text
}else{ // 新增一条记录
let context:NSManagedObjectContext = appDelegate.persistentContainer.viewContext
let note: Note = Note(context: context)
note.content = editTextView.text
note.createTime = NSDate()
}
appDelegate.saveContext()
self.navigationController?.popViewController(animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func keyboardWillShow(notification:NSNotification){
// 输入位置被键盘挡住时上移
let keyboardRect = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
if keyboardRect != nil {
self.editTextView.contentInset.bottom = keyboardRect!.height
}
}
func keyboardWillHide(notification:NSNotification){
// 输入框恢复原位
self.editTextView.contentInset.bottom = 0
}
}