Keystone Park App 学习笔记:CoreData CRUD

源自 NEW- CoreData for Swift Development (Swift 4.2 & iOS 12)

Entity

Entity: 是 Core Data 中的一个类,我们可以把实体类比为数据库中的表。其实也可以简单类比理解为 OC 中的类模型,我们自定义的类模型中将包含我们自己需要的属性。同样,实体类也将包含我们所需要的属性。

当添加完 Entities 后,可参照下图指引生成所有 Entities 对应的类文件。

Relationship Type

分为 To ManyTo One 两种,如下图所示:

在此 App 中每个学生只能选择一门课程,因此学生对课程是 To One 的关系。

而每门课程可以由多个学生选择,因此课程对学生是 To Many 关系。

Delete Rule

当删除某个课程后,Nullify 模式的后果是造成申报该课程的学生继续引用该课程,而该课程已经被删除了;Cascade 模式会关联删除,即删掉该课程的同时也会删掉所有申报该课程的学生;Deny 模式是当删除由学生申报的某课程时,会报错拒绝删除。

MVC

datamodel 目录下的文件定义了数据模型,service 目录下的文件提供了增删改查的接口,controller 目录下的文件用于设置视图。

LessonService

处理增删改查逻辑,并随时保存。保存时调用 AppDelegate 中的 persistentContainer.viewContext 对象,若失败即时 rollback()

需要注意的是数据和界面显示的一致性,比如在界面上删除了一行数据,ViewController 需要知道删除操作成功与否,因此设置一个回调函数更新界面。

class LessonService {
    func deleteLesson(lesson: Lesson, deleteHandler: @escaping (Bool) -> Void) {
        moc.delete(lesson)
        save(completion: deleteHandler)
    }
    
    private func save(completion: ((Bool) -> Void)? = nil) {
        let success: Bool
        
        do {
            try moc.save()
            success = true
        }
        catch let error as NSError {
            print("Save failed: \(error.localizedDescription)")
            moc.rollback()
            success = false
        }
        
        if let completion = completion {
            completion(success)
        }
    }
}

在 ViewController 中调用删除函数时,若成功则更新 tableView,若失败则弹框提示用户。

    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            lessonService?.deleteLesson(lesson: lessons[indexPath.row], deleteHandler: { [weak self] (success) in
                if success {
                    self?.lessons.remove(at: indexPath.row)
                    self?.tableView.deleteRows(at: [indexPath], with: .fade)
                }
                else {
                    let alertController = UIAlertController(title: "Delete Failed", message: "There are students currently register for this lesson", preferredStyle: .alert)
                    let alertAction = UIAlertAction(title: "OK", style: .default, handler: nil)
                    alertController.addAction(alertAction)
                    self?.present(alertController, animated: true, completion: nil)
                }
            })
        }
        
        tableView.reloadData()
    }

TableView delegate

滑动删除某行

    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
        tableView.reloadData()
    }

Swift 语法 typealias

类似于 C 语言中的 typedefine

typealias StudentHandler = (Bool, [Student]) -> ()

使用时:

func addStudent(name: String, for type: LessonType, completion: StudentHandler?) {}

Reference

Advertisements

分类:iOS

Tagged as: ,

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google+ photo

You are commenting using your Google+ account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理